diff --git a/.eslintrc.js b/.eslintrc.js index ce74b583..e08d79be 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,51 +1,35 @@ "use strict"; module.exports = { - "env": { - "node": true, - "es6": true + env: { + node: true, + es6: true, }, - "parserOptions": { - "ecmaVersion": 9 - }, + extends: ["prettier"], - "globals": { - "fetch": false, - "WebAssembly": false + parserOptions: { + ecmaVersion: 9, }, - "rules": { - // Require spacing around => - "arrow-spacing": "error", - - // Braces only needed for multi-line arrow function blocks - // "arrow-body-style": ["error", "as-needed"] + globals: { + fetch: false, + WebAssembly: false, + }, + rules: { // Always require spacing around a single line block "block-spacing": "error", - // No newline before open brace for a block - "brace-style": ["error", "1tbs", { "allowSingleLine": true }], - - // No space before always a space after a comma - "comma-spacing": ["error", {"after": true, "before": false}], - - // Commas at the end of the line not the start - "comma-style": "error", - // Warn about cyclomatic complexity in functions. // XXX Get this down to 20? - "complexity": ["error", 25], - - // Don't require spaces around computed properties - "computed-property-spacing": ["error", "never"], + complexity: ["error", 25], // Functions must always return something or nothing "consistent-return": "error", // Require braces around blocks that start a new line - "curly": ["error", "multi-line"], + curly: ["error", "multi-line"], // Encourage the use of dot notation whenever possible. "dot-notation": "error", @@ -53,25 +37,6 @@ module.exports = { // Always require a trailing EOL "eol-last": "error", - // No spaces between function name and parentheses - "func-call-spacing": "error", - - // Require function* name() - "generator-star-spacing": ["error", {"after": true, "before": false}], - - // Two space indent - // "indent": ["error", 2, { "SwitchCase": 1 }], - - // Space after colon not before in property declarations - "key-spacing": ["error", { - "afterColon": true, - "beforeColon": false, - "mode": "minimum" - }], - - // Require spaces before and after keywords - "keyword-spacing": "error", - // Unix linebreaks "linebreak-style": ["error", "unix"], @@ -125,7 +90,7 @@ module.exports = { "no-else-return": "error", // No empty statements - "no-empty": ["error", {"allowEmptyCatch": true}], + "no-empty": ["error", { allowEmptyCatch: true }], // No empty character classes in regex "no-empty-character-class": "error", @@ -145,9 +110,6 @@ module.exports = { // No using !! where casting to boolean is already happening "no-extra-boolean-cast": "error", - // No double semicolon - "no-extra-semi": "error", - // No overwriting defined functions "no-func-assign": "error", @@ -163,7 +125,7 @@ module.exports = { // Disallow the use of the __iterator__ property "no-iterator": "error", - // No labels + // No labels "no-labels": "error", // Disallow unnecessary nested blocks @@ -172,16 +134,18 @@ module.exports = { // No single if block inside an else block "no-lonely-if": "error", - // no-tabs disallows tabs completely. - // "no-mixed-spaces-and-tabs": "error", - // No unnecessary spacing - "no-multi-spaces": ["error", { exceptions: { - "ArrayExpression": true, - "AssignmentExpression": true, - "ObjectExpression": true, - "VariableDeclarator": true - } }], + "no-multi-spaces": [ + "error", + { + exceptions: { + ArrayExpression: true, + AssignmentExpression: true, + ObjectExpression: true, + VariableDeclarator: true, + }, + }, + ], // No reassigning native JS objects "no-native-reassign": "error", @@ -228,9 +192,6 @@ module.exports = { // Disallow tabs. "no-tabs": "error", - // No trailing whitespace - "no-trailing-spaces": "error", - // No using undeclared variables "no-undef": "error", @@ -250,10 +211,13 @@ module.exports = { "no-unsafe-negation": "error", // No declaring variables that are never used - "no-unused-vars": ["error", { - "args": "none", - "vars": "local" - }], + "no-unused-vars": [ + "error", + { + args: "none", + vars: "local", + }, + ], // No using variables before defined "no-use-before-define": ["error", "nofunc"], @@ -271,56 +235,18 @@ module.exports = { // Use const or let instead of var "no-var": "error", - // Disallow whitespace before properties. - "no-whitespace-before-property": "error", - // No using with "no-with": "error", // Require object-literal shorthand with ES6 method syntax - "object-shorthand": ["error", "always", { "avoidQuotes": true }], + "object-shorthand": ["error", "always", { avoidQuotes: true }], // Use const instead of let where possible "prefer-const": "error", - // Require double-quotes everywhere, except where quotes are escaped - // or template literals are used. - "quotes": ["error", "double", { - "allowTemplateLiterals": true, - "avoidEscape": true - }], - - // No spacing inside rest or spread expressions - "rest-spread-spacing": "error", - - // Always require semicolon at end of statement - "semi": ["error", "always"], - // Require space before blocks "space-before-blocks": "error", - // Never use spaces before function parentheses - "space-before-function-paren": ["error", { - "anonymous": "never", - "asyncArrow": "always", - "named": "never" - }], - - // No space padding in parentheses - "space-in-parens": ["error", "never"], - - // Require spaces around operators - "space-infix-ops": ["error", { "int32Hint": true }], - - // ++ and -- should not need spacing - "space-unary-ops": ["error", { - "nonwords": false, - "overrides": { - "typeof": false // We tend to use typeof as a function call - }, - "words": true - }], - // Requires or disallows a whitespace (space or tab) beginning a comment "spaced-comment": "error", @@ -328,6 +254,8 @@ module.exports = { "use-isnan": "error", // Only check typeof against valid results - "valid-typeof": "error" - } + "valid-typeof": "error", + + "max-len": ["error", { code: 120, ignoreUrls: true }], + }, }; diff --git a/.gitattributes b/.gitattributes index 4e271005..476ec9d3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,18 +1,2 @@ -dist/source-map.debug.js binary -dist/source-map.js binary -dist/source-map.min.js binary -dist/source-map.min.js.map binary - -dist/test/test_api.js binary -dist/test/test_array_set.js binary -dist/test/test_base64.js binary -dist/test/test_base64_vlq.js binary -dist/test/test_binary_search.js binary -dist/test/test_dog_fooding.js binary -dist/test/test_quick_sort.js binary -dist/test/test_source_map_consumer.js binary -dist/test/test_source_map_generator.js binary -dist/test/test_source_node.js binary -dist/test/test_util.js binary - bench/scalajs-runtime-sourcemap.js binary +wasm-mappings/benches/part-of-scala-js-source-map -diff -merge diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 00000000..5f0c402a --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,11 @@ +comment: + require_changes: true + +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml new file mode 100644 index 00000000..bb422d05 --- /dev/null +++ b/.github/workflows/cargo.yml @@ -0,0 +1,41 @@ +on: + pull_request: + branches: [master] + paths: + - wasm-mappings/** + - .github/workflows/cargo.yml + push: + branches: [master] + workflow_dispatch: + +name: WASM tests + +defaults: + run: + working-directory: ./wasm-mappings + +jobs: + build_and_test: + name: WASM mappings + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: [stable, beta, nightly] + job: [test, bench, wasm] + exclude: + - toolchain: stable + job: bench + - toolchain: stable + job: wasm + - toolchain: beta + job: bench + - toolchain: beta + job: wasm + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.toolchain }} + override: true + default: true + - run: JOB=${{ matrix.job }} ./ci/script.sh diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 00000000..bcb3d7b0 --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,39 @@ +name: Node.js + +on: + pull_request: + branches: [master] + push: + branches: [master] + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12, 14, 16, 18] + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm test + + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + - run: npm ci + - run: npm run lint + - run: npm run toc + - run: git diff --stat --exit-code + - run: npx prettier --check . + - run: npm run coverage + - run: npx c8 report --reporter=lcov + - uses: codecov/codecov-action@v3 diff --git a/.gitignore b/.gitignore index b81c6373..7abedbcf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ *.iml *.log .idea +.DS_Store node_modules/* build/ -package-lock.json bench/*.svg -.nyc_output/ +bench/dist/ +bench/node_modules coverage/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..163c0757 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/source-map-tests"] + path = test/source-map-tests + url = https://github.com/tc39/source-map-tests.git diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..9179b1bd --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +bench/ +coverage/ +node_modules/ +target/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..c2ad263b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "arrowParens": "avoid", + "endOfLine": "lf", + "printWidth": 80, + "tabWidth": 2, + "trailingComma": "es5" +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0bc39f18..00000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: node_js - -sudo: false - -node_js: - - "8" - - "9" - -install: -- npm install -- npm install coveralls - -script: -- npm run coverage - -after_success: -- nyc report --reporter=text-lcov | coveralls - -cache: - directories: - - node_modules - -os: - - linux - - osx diff --git a/.waiting.html b/.waiting.html deleted file mode 100644 index a964629d..00000000 --- a/.waiting.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - Code coverage report for All files - - - -
This page will refresh with a coverage report, as long as you have - executed npm run dev. Please be patient.
- - \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ef31a099..35f97a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,344 +1,378 @@ # Change Log +## 0.8.0-beta.0 + +### Breaking changes + +- [#350](https://github.com/mozilla/source-map/pull/350) - + Change browser detection logic for WASM loading. +- [#363](https://github.com/mozilla/source-map/pull/363) - + Change WASM loading detection to rely on `package.json#browser` field. +- [#362](https://github.com/mozilla/source-map/pull/362) - + Remove the `dist/` bundle. +- [#371](https://github.com/mozilla/source-map/pull/371) - + Reimplement sourcemap URL processing using the WHATWG URL API. + +### Nonbreaking changes: + +- [#339](https://github.com/mozilla/source-map/pull/339) - + Allow initializing the consumer `mappings.wasm` file as an `ArrayBuffer`. + +### Internal Improvements: + +- [#347](https://github.com/mozilla/source-map/pull/347) - + Improve tests. +- [#352](https://github.com/mozilla/source-map/pull/352) - + Improve documentation. +- [#361](https://github.com/mozilla/source-map/pull/361) - + Use newer Webpack CLI when bundling. +- [#364](https://github.com/mozilla/source-map/pull/364) - + Convert `IndexedSourceMapConsumer` implementation to pass more through + to `BasicSourceMapConsumer`. +- [#366](https://github.com/mozilla/source-map/pull/366) - + Normalize internal URL representation to be easier to follow. +- [#341](https://github.com/mozilla/source-map/pull/341) - + Use async functions to simplify `SourceMapConsumer.with` implementation. + ## 0.7.3 -* Fix a bug where nested uses of `SourceMapConsumer` could result in a +- Fix a bug where nested uses of `SourceMapConsumer` could result in a `TypeError`. [#338](https://github.com/mozilla/source-map/issues/338) [#330](https://github.com/mozilla/source-map/issues/330) [#319](https://github.com/mozilla/source-map/issues/319) ## 0.7.2 -* Another 3x speed up in `SourceMapConsumer`. Read about it here: +- Another 3x speed up in `SourceMapConsumer`. Read about it here: http://fitzgeraldnick.com/2018/02/26/speed-without-wizardry.html ## 0.7.1 -* Updated TypeScript typings. [#321][] +- Updated TypeScript typings. [#321][] [#321]: https://github.com/mozilla/source-map/pull/321 ## 0.7.0 -* `SourceMapConsumer` now uses WebAssembly, and is **much** faster! Read about +- `SourceMapConsumer` now uses WebAssembly, and is **much** faster! Read about it here: https://hacks.mozilla.org/2018/01/oxidizing-source-maps-with-rust-and-webassembly/ -* **Breaking change:** `new SourceMapConsumer` now returns a `Promise` object +- **Breaking change:** `new SourceMapConsumer` now returns a `Promise` object that resolves to the newly constructed `SourceMapConsumer` instance, rather than returning the new instance immediately. -* **Breaking change:** when you're done using a `SourceMapConsumer` instance, +- **Breaking change:** when you're done using a `SourceMapConsumer` instance, you must call `SourceMapConsumer.prototype.destroy` on it. After calling `destroy`, you must not use the instance again. -* **Breaking change:** `SourceMapConsumer` used to be able to handle lines, +- **Breaking change:** `SourceMapConsumer` used to be able to handle lines, columns numbers and source and name indices up to `2^53 - 1` (aka `Number.MAX_SAFE_INTEGER`). It can now only handle them up to `2^32 - 1`. -* **Breaking change:** The `source-map` library now uses modern ECMAScript-isms: +- **Breaking change:** The `source-map` library now uses modern ECMAScript-isms: `let`, arrow functions, `async`, etc. Use Babel to compile it down to ECMAScript 5 if you need to support older JavaScript environments. -* **Breaking change:** Drop support for Node < 8. If you want to support older -versions of node, please use v0.6 or below. +- **Breaking change:** Drop support for Node < 8. If you want to support older + versions of node, please use v0.6 or below. ## 0.5.6 -* Fix for regression when people were using numbers as names in source maps. See +- Fix for regression when people were using numbers as names in source maps. See #236. ## 0.5.5 -* Fix "regression" of unsupported, implementation behavior that half the world +- Fix "regression" of unsupported, implementation behavior that half the world happens to have come to depend on. See #235. -* Fix regression involving function hoisting in SpiderMonkey. See #233. +- Fix regression involving function hoisting in SpiderMonkey. See #233. ## 0.5.4 -* Large performance improvements to source-map serialization. See #228 and #229. +- Large performance improvements to source-map serialization. See #228 and #229. ## 0.5.3 -* Do not include unnecessary distribution files. See +- Do not include unnecessary distribution files. See commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86. ## 0.5.2 -* Include browser distributions of the library in package.json's `files`. See +- Include browser distributions of the library in package.json's `files`. See issue #212. ## 0.5.1 -* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See +- Fix latent bugs in IndexedSourceMapConsumer.prototype.\_parseMappings. See ff05274becc9e6e1295ed60f3ea090d31d843379. ## 0.5.0 -* Node 0.8 is no longer supported. +- Node 0.8 is no longer supported. -* Use webpack instead of dryice for bundling. +- Use webpack instead of dryice for bundling. -* Big speedups serializing source maps. See pull request #203. +- Big speedups serializing source maps. See pull request #203. -* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that +- Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that explicitly start with the source root. See issue #199. ## 0.4.4 -* Fix an issue where using a `SourceMapGenerator` after having created a +- Fix an issue where using a `SourceMapGenerator` after having created a `SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See issue #191. -* Fix an issue with where `SourceMapGenerator` would mistakenly consider +- Fix an issue with where `SourceMapGenerator` would mistakenly consider different mappings as duplicates of each other and avoid generating them. See issue #192. ## 0.4.3 -* A very large number of performance improvements, particularly when parsing +- A very large number of performance improvements, particularly when parsing source maps. Collectively about 75% of time shaved off of the source map parsing benchmark! -* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy +- Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy searching in the presence of a column option. See issue #177. -* Fix a bug with joining a source and its source root when the source is above +- Fix a bug with joining a source and its source root when the source is above the root. See issue #182. -* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to +- Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to determine when all sources' contents are inlined into the source map. See issue #190. ## 0.4.2 -* Add an `.npmignore` file so that the benchmarks aren't pulled down by +- Add an `.npmignore` file so that the benchmarks aren't pulled down by dependent projects. Issue #169. -* Add an optional `column` argument to +- Add an optional `column` argument to `SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines with no mappings. Issues #172 and #173. ## 0.4.1 -* Fix accidentally defining a global variable. #170. +- Fix accidentally defining a global variable. #170. ## 0.4.0 -* The default direction for fuzzy searching was changed back to its original +- The default direction for fuzzy searching was changed back to its original direction. See #164. -* There is now a `bias` option you can supply to `SourceMapConsumer` to control +- There is now a `bias` option you can supply to `SourceMapConsumer` to control the fuzzy searching direction. See #167. -* About an 8% speed up in parsing source maps. See #159. +- About an 8% speed up in parsing source maps. See #159. -* Added a benchmark for parsing and generating source maps. +- Added a benchmark for parsing and generating source maps. ## 0.3.0 -* Change the default direction that searching for positions fuzzes when there is +- Change the default direction that searching for positions fuzzes when there is not an exact match. See #154. -* Support for environments using json2.js for JSON serialization. See #156. +- Support for environments using json2.js for JSON serialization. See #156. ## 0.2.0 -* Support for consuming "indexed" source maps which do not have any remote +- Support for consuming "indexed" source maps which do not have any remote sections. See pull request #127. This introduces a minor backwards incompatibility if you are monkey patching `SourceMapConsumer.prototype` methods. ## 0.1.43 -* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue +- Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue #148 for some discussion and issues #150, #151, and #152 for implementations. ## 0.1.42 -* Fix an issue where `SourceNode`s from different versions of the source-map +- Fix an issue where `SourceNode`s from different versions of the source-map library couldn't be used in conjunction with each other. See issue #142. ## 0.1.41 -* Fix a bug with getting the source content of relative sources with a "./" +- Fix a bug with getting the source content of relative sources with a "./" prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768). -* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the +- Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the column span of each mapping. -* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find +- Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find all generated positions associated with a given original source and line. ## 0.1.40 -* Performance improvements for parsing source maps in SourceMapConsumer. +- Performance improvements for parsing source maps in SourceMapConsumer. ## 0.1.39 -* Fix a bug where setting a source's contents to null before any source content +- Fix a bug where setting a source's contents to null before any source content had been set before threw a TypeError. See issue #131. ## 0.1.38 -* Fix a bug where finding relative paths from an empty path were creating +- Fix a bug where finding relative paths from an empty path were creating absolute paths. See issue #129. ## 0.1.37 -* Fix a bug where if the source root was an empty string, relative source paths +- Fix a bug where if the source root was an empty string, relative source paths would turn into absolute source paths. Issue #124. ## 0.1.36 -* Allow the `names` mapping property to be an empty string. Issue #121. +- Allow the `names` mapping property to be an empty string. Issue #121. ## 0.1.35 -* A third optional parameter was added to `SourceNode.fromStringWithSourceMap` +- A third optional parameter was added to `SourceNode.fromStringWithSourceMap` to specify a path that relative sources in the second parameter should be relative to. Issue #105. -* If no file property is given to a `SourceMapGenerator`, then the resulting +- If no file property is given to a `SourceMapGenerator`, then the resulting source map will no longer have a `null` file property. The property will simply not exist. Issue #104. -* Fixed a bug where consecutive newlines were ignored in `SourceNode`s. +- Fixed a bug where consecutive newlines were ignored in `SourceNode`s. Issue #116. ## 0.1.34 -* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. +- Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. -* Fix bug involving source contents and the +- Fix bug involving source contents and the `SourceMapGenerator.prototype.applySourceMap`. Issue #100. ## 0.1.33 -* Fix some edge cases surrounding path joining and URL resolution. +- Fix some edge cases surrounding path joining and URL resolution. -* Add a third parameter for relative path to +- Add a third parameter for relative path to `SourceMapGenerator.prototype.applySourceMap`. -* Fix issues with mappings and EOLs. +- Fix issues with mappings and EOLs. ## 0.1.32 -* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns +- Fixed a bug where SourceMapConsumer couldn't handle negative relative columns (issue 92). -* Fixed test runner to actually report number of failed tests as its process +- Fixed test runner to actually report number of failed tests as its process exit code. -* Fixed a typo when reporting bad mappings (issue 87). +- Fixed a typo when reporting bad mappings (issue 87). ## 0.1.31 -* Delay parsing the mappings in SourceMapConsumer until queried for a source +- Delay parsing the mappings in SourceMapConsumer until queried for a source location. -* Support Sass source maps (which at the time of writing deviate from the spec +- Support Sass source maps (which at the time of writing deviate from the spec in small ways) in SourceMapConsumer. ## 0.1.30 -* Do not join source root with a source, when the source is a data URI. +- Do not join source root with a source, when the source is a data URI. -* Extend the test runner to allow running single specific test files at a time. +- Extend the test runner to allow running single specific test files at a time. -* Performance improvements in `SourceNode.prototype.walk` and +- Performance improvements in `SourceNode.prototype.walk` and `SourceMapConsumer.prototype.eachMapping`. -* Source map browser builds will now work inside Workers. +- Source map browser builds will now work inside Workers. -* Better error messages when attempting to add an invalid mapping to a +- Better error messages when attempting to add an invalid mapping to a `SourceMapGenerator`. ## 0.1.29 -* Allow duplicate entries in the `names` and `sources` arrays of source maps +- Allow duplicate entries in the `names` and `sources` arrays of source maps (usually from TypeScript) we are parsing. Fixes github issue 72. ## 0.1.28 -* Skip duplicate mappings when creating source maps from SourceNode; github +- Skip duplicate mappings when creating source maps from SourceNode; github issue 75. ## 0.1.27 -* Don't throw an error when the `file` property is missing in SourceMapConsumer, +- Don't throw an error when the `file` property is missing in SourceMapConsumer, we don't use it anyway. ## 0.1.26 -* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. +- Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. ## 0.1.25 -* Make compatible with browserify +- Make compatible with browserify ## 0.1.24 -* Fix issue with absolute paths and `file://` URIs. See +- Fix issue with absolute paths and `file://` URIs. See https://bugzilla.mozilla.org/show_bug.cgi?id=885597 ## 0.1.23 -* Fix issue with absolute paths and sourcesContent, github issue 64. +- Fix issue with absolute paths and sourcesContent, github issue 64. ## 0.1.22 -* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. +- Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. ## 0.1.21 -* Fixed handling of sources that start with a slash so that they are relative to +- Fixed handling of sources that start with a slash so that they are relative to the source root's host. ## 0.1.20 -* Fixed github issue #43: absolute URLs aren't joined with the source root +- Fixed github issue #43: absolute URLs aren't joined with the source root anymore. ## 0.1.19 -* Using Travis CI to run tests. +- Using Travis CI to run tests. ## 0.1.18 -* Fixed a bug in the handling of sourceRoot. +- Fixed a bug in the handling of sourceRoot. ## 0.1.17 -* Added SourceNode.fromStringWithSourceMap. +- Added SourceNode.fromStringWithSourceMap. ## 0.1.16 -* Added missing documentation. +- Added missing documentation. -* Fixed the generating of empty mappings in SourceNode. +- Fixed the generating of empty mappings in SourceNode. ## 0.1.15 -* Added SourceMapGenerator.applySourceMap. +- Added SourceMapGenerator.applySourceMap. ## 0.1.14 -* The sourceRoot is now handled consistently. +- The sourceRoot is now handled consistently. ## 0.1.13 -* Added SourceMapGenerator.fromSourceMap. +- Added SourceMapGenerator.fromSourceMap. ## 0.1.12 -* SourceNode now generates empty mappings too. +- SourceNode now generates empty mappings too. ## 0.1.11 -* Added name support to SourceNode. +- Added name support to SourceNode. ## 0.1.10 -* Added sourcesContent support to the customer and generator. +- Added sourcesContent support to the customer and generator. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..0d424fd8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,16 @@ +# Community Participation Guidelines + +This repository is governed by Mozilla's code of conduct and etiquette guidelines. +For more details, please read the +[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). + +## How to Report + +For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page. + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 053a5ab8..c3509743 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,13 +3,16 @@ Thank you for your interest in contributing to this library! Contributions are very appreciated. --------------------------------------------------------------------------------- +If you want help or mentorship, reach out to us in a GitHub issue, +or over Matrix in [source-map on mozilla.org](https://matrix.to/#/#source-map:mozilla.org) +and introduce yourself. - +--- + +## Table of Contents -## Table of Contents - [Filing Issues](#filing-issues) - [Building From Source](#building-from-source) @@ -21,25 +24,23 @@ very appreciated. - - ## Filing Issues If you are filing an issue for a bug or other misbehavior, please provide: -* **A test case.** The more minimal the better, but sometimes a larger test case +- **A test case.** The more minimal the better, but sometimes a larger test case cannot be helped. This should be in the form of a gist, node script, repository, etc. -* **Steps to reproduce the bug.** The more exact and specific the better. +- **Steps to reproduce the bug.** The more exact and specific the better. -* **The result you expected.** +- **The result you expected.** -* **The actual result.** +- **The actual result.** ## Building From Source -Install Node.js `8` or greater and then run +Install Node.js `12` or greater and then run $ git clone https://github.com/mozilla/source-map.git $ cd source-map/ @@ -51,7 +52,7 @@ Next, run This will create the following files: -* `dist/source-map.js` - The plain browser build. +- `dist/source-map.js` - The plain browser build. ## Submitting Pull Requests @@ -64,7 +65,7 @@ force push to the remote branch to update the pull request. ## Running Tests -The test suite is written for node.js. Install node.js `8` or greater and +The test suite is written for node.js. Install node.js `12` or greater and then run the tests with `npm test`: ```shell @@ -93,15 +94,15 @@ suite. The `assert` argument is a cut down version of node's assert module. You have access to the following assertion functions: -* `doesNotThrow` +- `doesNotThrow` -* `equal` +- `equal` -* `ok` +- `ok` -* `strictEqual` +- `strictEqual` -* `throws` +- `throws` (The reason for the restricted set of test functions is because we need the tests to run inside Firefox's test suite as well and Firefox has a shimmed @@ -111,31 +112,19 @@ There are additional test utilities and helpers in `./test/util.js` which you can use as well: ```js -var util = require('./util'); +var util = require("./util"); ``` ## Checking code coverage -It's fun to find ways to test lines of code that aren't visited by -the tests yet. +It's fun to find ways to test lines of code that aren't visited by the tests yet. ```shell $ npm run coverage $ open coverage/index.html ``` -This will allow you to browse to red sections of the code that need -more attention. Even more cool, however, is to run: - -```shell -$ npm run dev -``` - -(On some operating systems, this may pop up a request for node to be able to open a socket. Click "Allow" or the equivalent.) - -This will run the coverage tools, and monitor all of the files in the -project, re-running the coverage tools and refreshing the browser when -any files change. There will be a small web server running on port 4103 to enable this. Control-C to stop. +This will allow you to browse to red sections of the code that need more attention. ## Updating the `lib/mappings.wasm` WebAssembly Module @@ -153,11 +142,10 @@ $ rustup toolchain install nightly $ rustup target add wasm32-unknown-unknown --toolchain nightly ``` -Next, clone the Rust source used to create `lib/mappings.wasm`: +Move to wasm sources folder: ``` -$ git clone https://github.com/fitzgen/source-map-mappings.git -$ cd source-map-mappings/ +$ cd wasm-mappings/ ``` Make sure the crate's tests pass: @@ -173,9 +161,13 @@ Ensure that you have the following wasm post-processing tools installed: - `wasm-snip`: https://github.com/fitzgen/wasm-snip - `wasm-opt`: https://github.com/WebAssembly/binaryen +(These dependencies should automatically be installed by cargo) + Build Rust crate as a `.wasm` file: ``` $ cd source-map-mappings-wasm-api/ -$ ./build.py -o path/to/source-map/lib/mappings.wasm +$ ./build.py -o ../../lib/mappings.wasm ``` + +See further information in [wasm-mappings/CONTRIBUTING.md]. diff --git a/README.md b/README.md index 56e5ac3e..72402e35 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ # Source Map -[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map) - -[![Coverage Status](https://coveralls.io/repos/github/mozilla/source-map/badge.svg)](https://coveralls.io/github/mozilla/source-map) - [![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map) This is a library to generate and consume the source map format @@ -17,20 +13,21 @@ This is a library to generate and consume the source map format ## Use on the Web - - +```html + + +``` --------------------------------------------------------------------------------- +--- - +## Table of Contents -## Table of Contents - [Examples](#examples) - [Consuming a source map](#consuming-a-source-map) @@ -79,33 +76,37 @@ This is a library to generate and consume the source map format ```js const rawSourceMap = { version: 3, - file: 'min.js', - names: ['bar', 'baz', 'n'], - sources: ['one.js', 'two.js'], - sourceRoot: 'http://example.com/www/js/', - mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' + file: "min.js", + names: ["bar", "baz", "n"], + sources: ["one.js", "two.js"], + sourceRoot: "http://example.com/www/js/", + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; const whatever = await SourceMapConsumer.with(rawSourceMap, null, consumer => { - console.log(consumer.sources); // [ 'http://example.com/www/js/one.js', // 'http://example.com/www/js/two.js' ] - console.log(consumer.originalPositionFor({ - line: 2, - column: 28 - })); + console.log( + consumer.originalPositionFor({ + line: 2, + column: 28, + }) + ); // { source: 'http://example.com/www/js/two.js', // line: 2, // column: 10, // name: 'n' } - console.log(consumer.generatedPositionFor({ - source: 'http://example.com/www/js/two.js', - line: 2, - column: 10 - })); + console.log( + consumer.generatedPositionFor({ + source: "http://example.com/www/js/two.js", + line: 2, + column: 10, + }) + ); // { line: 2, column: 28 } consumer.eachMapping(function (m) { @@ -126,30 +127,32 @@ In depth guide: ```js function compile(ast) { switch (ast.type) { - case 'BinaryExpression': - return new SourceNode( - ast.location.line, - ast.location.column, - ast.location.source, - [compile(ast.left), " + ", compile(ast.right)] - ); - case 'Literal': - return new SourceNode( - ast.location.line, - ast.location.column, - ast.location.source, - String(ast.value) - ); - // ... - default: - throw new Error("Bad AST"); + case "BinaryExpression": + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + [compile(ast.left), " + ", compile(ast.right)] + ); + case "Literal": + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + String(ast.value) + ); + // ... + default: + throw new Error("Bad AST"); } } var ast = parse("40 + 2", "add.js"); -console.log(compile(ast).toStringWithSourceMap({ - file: 'add.js' -})); +console.log( + compile(ast).toStringWithSourceMap({ + file: "add.js", + }) +); // { code: '40 + 2', // map: [object SourceMapGenerator] } ``` @@ -158,20 +161,20 @@ console.log(compile(ast).toStringWithSourceMap({ ```js var map = new SourceMapGenerator({ - file: "source-mapped.js" + file: "source-mapped.js", }); map.addMapping({ generated: { line: 10, - column: 35 + column: 35, }, source: "foo.js", original: { line: 33, - column: 2 + column: 2, }, - name: "christopher" + name: "christopher", }); console.log(map.toString()); @@ -184,7 +187,7 @@ Get a reference to the module: ```js // Node.js -var sourceMap = require('source-map'); +var sourceMap = require("source-map"); // Browser builds var sourceMap = window.sourceMap; @@ -207,12 +210,12 @@ calling `initialize` before constructing any `SourceMapConsumer`s. The options object has the following properties: -* `"lib/mappings.wasm"`: A `String` containing the URL of the +- `"lib/mappings.wasm"`: A `String` containing the URL of the `lib/mappings.wasm` file, or an `ArrayBuffer` with the contents of `lib/mappings.wasm`. ```js sourceMap.SourceMapConsumer.initialize({ - "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" + "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm", }); ``` @@ -222,20 +225,24 @@ The only parameter is the raw source map (either as a string which can be `JSON.parse`'d, or an object). According to the spec, source maps have the following attributes: -* `version`: Which version of the source map spec this map is following. +- `version`: Which version of the source map spec this map is following. -* `sources`: An array of URLs to the original source files. +- `sources`: An array of URLs to the original source files. -* `names`: An array of identifiers which can be referenced by individual +- `names`: An array of identifiers which can be referenced by individual mappings. -* `sourceRoot`: Optional. The URL root from which all sources are relative. +- `sourceRoot`: Optional. The URL root from which all sources are relative. + +- `sourcesContent`: Optional. An array of contents of the original source files. -* `sourcesContent`: Optional. An array of contents of the original source files. +- `mappings`: A string of base64 VLQs which contain the actual mappings. -* `mappings`: A string of base64 VLQs which contain the actual mappings. +- `file`: Optional. The generated filename this source map is associated with. -* `file`: Optional. The generated filename this source map is associated with. +- `x_google_ignoreList`: Optional. An additional extension field which is an array + of indices refering to urls in the sources array. This is used to identify third-party + sources, that the developer might want to avoid when debugging. [Read more](https://developer.chrome.com/articles/x-google-ignore-list/) The promise of the constructed souce map consumer is returned. @@ -254,8 +261,7 @@ to call `destroy`. #### SourceMapConsumer.with Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl` -(see the `SourceMapConsumer` constructor for details. Then, invoke the `async -function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait +(see the `SourceMapConsumer` constructor for details. Then, invoke the `async function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait for `f` to complete, call `destroy` on the consumer, and return `f`'s return value. @@ -300,7 +306,7 @@ inclusive. ```js // Before: -consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }); // [ { line: 2, // column: 1 }, // { line: 2, @@ -311,7 +317,7 @@ consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) consumer.computeColumnSpans(); // After: -consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }); // [ { line: 2, // column: 1, // lastColumn: 9 }, @@ -329,41 +335,44 @@ Returns the original source, line, and column information for the generated source's line and column positions provided. The only argument is an object with the following properties: -* `line`: The line number in the generated source. Line numbers in +- `line`: The line number in the generated source. Line numbers in this library are 1-based (note that the underlying source map specification uses 0-based line numbers -- this library handles the translation). -* `column`: The column number in the generated source. Column numbers +- `column`: The column number in the generated source. Column numbers in this library are 0-based. -* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or +- `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest element that is smaller than or greater than the one we are searching for, - respectively, if the exact element cannot be found. Defaults to + respectively, if the exact element cannot be found. Defaults to `SourceMapConsumer.GREATEST_LOWER_BOUND`. and an object is returned with the following properties: -* `source`: The original source file, or null if this information is not +- `source`: The original source file, or null if this information is not available. -* `line`: The line number in the original source, or null if this information is - not available. The line number is 1-based. +- `line`: The line number in the original source, or null if this information is + not available. The line number is 1-based. -* `column`: The column number in the original source, or null if this - information is not available. The column number is 0-based. +- `column`: The column number in the original source, or null if this + information is not available. The column number is 0-based. -* `name`: The original identifier, or null if this information is not available. +- `name`: The original identifier, or null if this information is not available. ```js -consumer.originalPositionFor({ line: 2, column: 10 }) +consumer.originalPositionFor({ line: 2, column: 10 }); // { source: 'foo.coffee', // line: 2, // column: 2, // name: null } -consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) +consumer.originalPositionFor({ + line: 99999999999999999, + column: 999999999999999, +}); // { source: null, // line: null, // column: null, @@ -376,24 +385,24 @@ Returns the generated line and column information for the original source, line, and column positions provided. The only argument is an object with the following properties: -* `source`: The filename of the original source. +- `source`: The filename of the original source. -* `line`: The line number in the original source. The line number is +- `line`: The line number in the original source. The line number is 1-based. -* `column`: The column number in the original source. The column +- `column`: The column number in the original source. The column number is 0-based. and an object is returned with the following properties: -* `line`: The line number in the generated source, or null. The line +- `line`: The line number in the generated source, or null. The line number is 1-based. -* `column`: The column number in the generated source, or null. The +- `column`: The column number in the generated source, or null. The column number is 0-based. ```js -consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) +consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }); // { line: 1, // column: 56 } ``` @@ -409,24 +418,24 @@ that has any offsets. The only argument is an object with the following properties: -* `source`: The filename of the original source. +- `source`: The filename of the original source. -* `line`: The line number in the original source. The line number is +- `line`: The line number in the original source. The line number is 1-based. -* `column`: Optional. The column number in the original source. The +- `column`: Optional. The column number in the original source. The column number is 0-based. and an array of objects is returned, each with the following properties: -* `line`: The line number in the generated source, or null. The line +- `line`: The line number in the generated source, or null. The line number is 1-based. -* `column`: The column number in the generated source, or null. The +- `column`: The column number in the generated source, or null. The column number is 0-based. ```js -consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }); // [ { line: 2, // column: 1 }, // { line: 2, @@ -464,10 +473,10 @@ thrown. Optionally, pass `true` as the second param to have `null` returned instead. ```js -consumer.sources +consumer.sources; // [ "my-cool-lib.clj" ] -consumer.sourceContentFor("my-cool-lib.clj") +consumer.sourceContentFor("my-cool-lib.clj"); // "..." consumer.sourceContentFor("this is not in the source map"); @@ -482,21 +491,22 @@ consumer.sourceContentFor("this is not in the source map", true); Iterate over each mapping between an original source/line/column and a generated line/column in this source map. -* `callback`: The function that is called with each mapping. Mappings have the - form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, - name }` +- `callback`: The function that is called with each mapping. Mappings have the + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }` -* `context`: Optional. If specified, this object will be the value of `this` +- `context`: Optional. If specified, this object will be the value of `this` every time that `callback` is called. -* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or +- `order`: Either `SourceMapConsumer.GENERATED_ORDER` or `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over the mappings sorted by the generated file's line/column order or the original's source/line/column order, respectively. Defaults to `SourceMapConsumer.GENERATED_ORDER`. ```js -consumer.eachMapping(function (m) { console.log(m); }) +consumer.eachMapping(function (m) { + console.log(m); +}); // ... // { source: 'illmatic.js', // generatedLine: 1, @@ -512,6 +522,7 @@ consumer.eachMapping(function (m) { console.log(m); }) // name: null } // ... ``` + ### SourceMapGenerator An instance of the SourceMapGenerator represents a source map which is being @@ -521,12 +532,12 @@ built incrementally. You may pass an object with the following properties: -* `file`: The filename of the generated source that this source map is +- `file`: The filename of the generated source that this source map is associated with. -* `sourceRoot`: A root for all relative URLs in this source map. +- `sourceRoot`: A root for all relative URLs in this source map. -* `skipValidation`: Optional. When `true`, disables validation of mappings as +- `skipValidation`: Optional. When `true`, disables validation of mappings as they are added. This can improve performance but should be used with discretion, as a last resort. Even then, one should avoid using this flag when running tests, if possible. @@ -534,7 +545,7 @@ You may pass an object with the following properties: ```js var generator = new sourceMap.SourceMapGenerator({ file: "my-generated-javascript-file.js", - sourceRoot: "http://example.com/app/js/" + sourceRoot: "http://example.com/app/js/", }); ``` @@ -542,7 +553,7 @@ var generator = new sourceMap.SourceMapGenerator({ Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance. -* `sourceMapConsumer` The SourceMap. +- `sourceMapConsumer` The SourceMap. ```js var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer); @@ -554,33 +565,35 @@ Add a single mapping from original source line and column to the generated source's line and column for this source map being created. The mapping object should have the following properties: -* `generated`: An object with the generated line and column positions. +- `generated`: An object with the generated line and column positions. -* `original`: An object with the original line and column positions. +- `original`: An object with the original line and column positions. -* `source`: The original source file (relative to the sourceRoot). +- `source`: The original source file (relative to the sourceRoot). -* `name`: An optional original token name for this mapping. +- `name`: An optional original token name for this mapping. ```js generator.addMapping({ source: "module-one.scm", original: { line: 128, column: 0 }, - generated: { line: 3, column: 456 } -}) + generated: { line: 3, column: 456 }, +}); ``` #### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) Set the source content for an original source file. -* `sourceFile` the URL of the original source file. +- `sourceFile` the URL of the original source file. -* `sourceContent` the content of the source file. +- `sourceContent` the content of the source file. ```js -generator.setSourceContent("module-one.scm", - fs.readFileSync("path/to/module-one.scm")) +generator.setSourceContent( + "module-one.scm", + fs.readFileSync("path/to/module-one.scm") +); ``` #### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) @@ -590,13 +603,13 @@ Each mapping to the supplied source file is rewritten using the supplied SourceMap. Note: The resolution for the resulting mappings is the minimum of this map and the supplied map. -* `sourceMapConsumer`: The SourceMap to be applied. +- `sourceMapConsumer`: The SourceMap to be applied. -* `sourceFile`: Optional. The filename of the source file. +- `sourceFile`: Optional. The filename of the source file. If omitted, sourceMapConsumer.file will be used, if it exists. Otherwise an error will be thrown. -* `sourceMapPath`: Optional. The dirname of the path to the SourceMap +- `sourceMapPath`: Optional. The dirname of the path to the SourceMap to be applied. If relative, it is relative to the SourceMap. This parameter is needed when the two SourceMaps aren't in the same @@ -612,7 +625,7 @@ is the minimum of this map and the supplied map. Renders the source map being generated to a string. ```js -generator.toString() +generator.toString(); // '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}' ``` @@ -626,19 +639,19 @@ use before outputting the generated JS and source map. #### new SourceNode([line, column, source[, chunk[, name]]]) -* `line`: The original line number associated with this source node, or null if - it isn't associated with an original line. The line number is 1-based. +- `line`: The original line number associated with this source node, or null if + it isn't associated with an original line. The line number is 1-based. -* `column`: The original column number associated with this source node, or null - if it isn't associated with an original column. The column number +- `column`: The original column number associated with this source node, or null + if it isn't associated with an original column. The column number is 0-based. -* `source`: The original source's filename; null if no filename is provided. +- `source`: The original source's filename; null if no filename is provided. -* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see +- `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see below. -* `name`: Optional. The original identifier. +- `name`: Optional. The original identifier. ```js var node = new SourceNode(1, 2, "a.cpp", [ @@ -652,24 +665,29 @@ var node = new SourceNode(1, 2, "a.cpp", [ Creates a SourceNode from generated code and a SourceMapConsumer. -* `code`: The generated code +- `code`: The generated code -* `sourceMapConsumer` The SourceMap for the generated code +- `sourceMapConsumer` The SourceMap for the generated code -* `relativePath` The optional path that relative sources in `sourceMapConsumer` +- `relativePath` The optional path that relative sources in `sourceMapConsumer` should be relative to. ```js -const consumer = await new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); -const node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), consumer); +const consumer = await new SourceMapConsumer( + fs.readFileSync("path/to/my-file.js.map", "utf8") +); +const node = SourceNode.fromStringWithSourceMap( + fs.readFileSync("path/to/my-file.js"), + consumer +); ``` #### SourceNode.prototype.add(chunk) Add a chunk of generated JS to this source node. -* `chunk`: A string snippet of generated JS code, another instance of - `SourceNode`, or an array where each member is one of those things. +- `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. ```js node.add(" + "); @@ -681,8 +699,8 @@ node.add([leftHandOperandNode, " + ", rightHandOperandNode]); Prepend a chunk of generated JS to this source node. -* `chunk`: A string snippet of generated JS code, another instance of - `SourceNode`, or an array where each member is one of those things. +- `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. ```js node.prepend("/** Build Id: f783haef86324gf **/\n\n"); @@ -693,13 +711,15 @@ node.prepend("/** Build Id: f783haef86324gf **/\n\n"); Set the source content for a source file. This will be added to the `SourceMap` in the `sourcesContent` field. -* `sourceFile`: The filename of the source file +- `sourceFile`: The filename of the source file -* `sourceContent`: The content of the source file +- `sourceContent`: The content of the source file ```js -node.setSourceContent("module-one.scm", - fs.readFileSync("path/to/module-one.scm")) +node.setSourceContent( + "module-one.scm", + fs.readFileSync("path/to/module-one.scm") +); ``` #### SourceNode.prototype.walk(fn) @@ -708,19 +728,18 @@ Walk over the tree of JS snippets in this node and its children. The walking function is called once for each snippet of JS and is passed that snippet and the its original associated source's line/column location. -* `fn`: The traversal function. +- `fn`: The traversal function. ```js var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", - [ - "tres", - new SourceNode(5, 6, "c.js", "quatro") - ] + ["tres", new SourceNode(5, 6, "c.js", "quatro")], ]); -node.walk(function (code, loc) { console.log("WALK:", code, loc); }) +node.walk(function (code, loc) { + console.log("WALK:", code, loc); +}); // WALK: uno { source: 'b.js', line: 3, column: 4, name: null } // WALK: dos { source: 'a.js', line: 1, column: 2, name: null } // WALK: tres { source: 'a.js', line: 1, column: 2, name: null } @@ -732,7 +751,7 @@ node.walk(function (code, loc) { console.log("WALK:", code, loc); }) Walk over the tree of SourceNodes. The walking function is called for each source file content and is passed the filename and source content. -* `fn`: The traversal function. +- `fn`: The traversal function. ```js var a = new SourceNode(1, 2, "a.js", "generated from a"); @@ -743,7 +762,9 @@ var c = new SourceNode(1, 2, "c.js", "generated from c"); c.setSourceContent("c.js", "original c"); var node = new SourceNode(null, null, null, [a, b, c]); -node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) +node.walkSourceContents(function (source, contents) { + console.log("WALK:", source, ":", contents); +}); // WALK: a.js : original a // WALK: b.js : original b // WALK: c.js : original c @@ -754,14 +775,14 @@ node.walkSourceContents(function (source, contents) { console.log("WALK:", sourc Like `Array.prototype.join` except for SourceNodes. Inserts the separator between each of this source node's children. -* `sep`: The separator. +- `sep`: The separator. ```js var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); var operand = new SourceNode(3, 4, "a.rs", "="); var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); -var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); +var node = new SourceNode(null, null, null, [lhs, operand, rhs]); var joinedNode = node.join(" "); ``` @@ -770,9 +791,9 @@ var joinedNode = node.join(" "); Call `String.prototype.replace` on the very right-most source snippet. Useful for trimming white space from the end of a source node, etc. -* `pattern`: The pattern to replace. +- `pattern`: The pattern to replace. -* `replacement`: The thing to replace the pattern with. +- `replacement`: The thing to replace the pattern with. ```js // Trim trailing white space. @@ -788,13 +809,10 @@ concatenates all the various snippets together to one string. var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", - [ - "tres", - new SourceNode(5, 6, "c.js", "quatro") - ] + ["tres", new SourceNode(5, 6, "c.js", "quatro")], ]); -node.toString() +node.toString(); // 'unodostresquatro' ``` @@ -810,13 +828,10 @@ The arguments are the same as those to `new SourceMapGenerator`. var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", - [ - "tres", - new SourceNode(5, 6, "c.js", "quatro") - ] + ["tres", new SourceNode(5, 6, "c.js", "quatro")], ]); -node.toStringWithSourceMap({ file: "my-output-file.js" }) +node.toStringWithSourceMap({ file: "my-output-file.js" }); // { code: 'unodostresquatro', // map: [object SourceMapGenerator] } ``` diff --git a/bench/bench-dom-bindings.js b/bench/bench-dom-bindings.js index b4650a42..fe321eb5 100644 --- a/bench/bench-dom-bindings.js +++ b/bench/bench-dom-bindings.js @@ -1,5 +1,5 @@ sourceMap.SourceMapConsumer.initialize({ - "lib/mappings.wasm": "../lib/mappings.wasm?bust_cache=" + String(Math.random()).replace(/0\./, ""), + "lib/mappings.wasm": "../lib/mappings.wasm?bust_cache=" + String(Math.random()).replace(/0\./, "") }); function bindRange(labelId, updater) { @@ -68,28 +68,28 @@ const updateImplAndBrowser = () => { implAndBrowserInput.addEventListener("input", updateImplAndBrowser); updateImplAndBrowser(); - // Run a benchmark when the given button is clicked and display results in the // given element. function benchOnClick(button, results, benchName, bencher) { - button.addEventListener("click", async function (e) { - e.preventDefault(); + button.addEventListener( + "click", + async function(e) { + e.preventDefault(); - const buttons = [...document.querySelectorAll("button")]; - buttons.forEach(b => b.setAttribute("disabled", true)); - results.innerHTML = ""; - await new Promise(r => requestAnimationFrame(r)); + const buttons = [...document.querySelectorAll("button")]; + buttons.forEach(b => b.setAttribute("disabled", true)); + results.innerHTML = ""; + await new Promise(r => requestAnimationFrame(r)); - var stats = await bencher(); + var stats = await bencher(); - buttons.forEach(b => b.removeAttribute("disabled")); + buttons.forEach(b => b.removeAttribute("disabled")); - const csv = stats - .xs - .map(x => `"${implAndBrowser}",${testSourceMap.mappings.length},"${benchName}",${x}`) - .join("\n"); + const csv = stats.xs + .map(x => `"${implAndBrowser}",${testSourceMap.mappings.length},"${benchName}",${x}`) + .join("\n"); - results.innerHTML = ` + results.innerHTML = ` @@ -110,7 +110,9 @@ function benchOnClick(button, results, benchName, bencher) {
${csv}
`; - }, false); + }, + false + ); } for (let bench of Object.keys(benchmarks)) { diff --git a/bench/bench.html b/bench/bench.html index 3bd14035..6445ab52 100644 --- a/bench/bench.html +++ b/bench/bench.html @@ -24,53 +24,53 @@

Benchmark mozilla/source-map

-

- -

-

- -

-

- -

-

- -

-

- -

+

+ +

+

+ +

+

+ +

+

+ +

+

+ +

- + diff --git a/bench/bench.js b/bench/bench.js index 82804f91..c896de4d 100644 --- a/bench/bench.js +++ b/bench/bench.js @@ -15,13 +15,13 @@ if (!console.profile) { var __benchmarkResults = []; var benchmarkBlackbox = [].push.bind(__benchmarkResults); -const now = typeof window === "object" && window.performance && window.performance.now - ? () => window.performance.now() - : () => now(); +const now = + typeof window === "object" && window.performance && window.performance.now + ? () => window.performance.now() + : () => now(); -const yieldForTick = typeof setTimeout === "function" - ? () => new Promise(resolve => setTimeout(resolve, 1)) - : () => Promise.resolve(); +const yieldForTick = + typeof setTimeout === "function" ? () => new Promise(resolve => setTimeout(resolve, 1)) : () => Promise.resolve(); // Benchmark running an action n times. async function benchmark(setup, action, tearDown = () => {}) { @@ -70,7 +70,7 @@ var benchmarks = { "SourceMapGenerator#toString": () => { let smg; return benchmark( - async function () { + async function() { var smc = await new sourceMap.SourceMapConsumer(testSourceMap); smg = sourceMap.SourceMapGenerator.fromSourceMap(smc); smc.destroy(); @@ -84,16 +84,18 @@ var benchmarks = { "set.first.breakpoint": () => { let testMapping; return benchmark( - async function () { + async function() { testMapping = await getTestMapping(); }, - async function () { + async function() { let smc = await new sourceMap.SourceMapConsumer(testSourceMap); - benchmarkBlackbox(smc.allGeneratedPositionsFor({ - source: testMapping.source, - line: testMapping.originalLine, - }).length); + benchmarkBlackbox( + smc.allGeneratedPositionsFor({ + source: testMapping.source, + line: testMapping.originalLine + }).length + ); smc.destroy(); } @@ -103,16 +105,18 @@ var benchmarks = { "first.pause.at.exception": () => { let testMapping; return benchmark( - async function () { + async function() { testMapping = await getTestMapping(); }, - async function () { + async function() { let smc = await new sourceMap.SourceMapConsumer(testSourceMap); - benchmarkBlackbox(smc.originalPositionFor({ - line: testMapping.generatedLine, - column: testMapping.generatedColumn, - })); + benchmarkBlackbox( + smc.originalPositionFor({ + line: testMapping.generatedLine, + column: testMapping.generatedColumn + }) + ); smc.destroy(); } @@ -123,71 +127,72 @@ var benchmarks = { let testMapping; let smc; return benchmark( - async function () { + async function() { testMapping = await getTestMapping(); smc = await new sourceMap.SourceMapConsumer(testSourceMap); }, - async function () { - benchmarkBlackbox(smc.allGeneratedPositionsFor({ - source: testMapping.source, - line: testMapping.originalLine, - })); + async function() { + benchmarkBlackbox( + smc.allGeneratedPositionsFor({ + source: testMapping.source, + line: testMapping.originalLine + }) + ); }, - function () { + function() { smc.destroy(); } - ) + ); }, "subsequent.pausing.at.exceptions": () => { let testMapping; let smc; return benchmark( - async function () { + async function() { testMapping = await getTestMapping(); smc = await new sourceMap.SourceMapConsumer(testSourceMap); }, - async function () { - benchmarkBlackbox(smc.originalPositionFor({ - line: testMapping.generatedLine, - column: testMapping.generatedColumn, - })); + async function() { + benchmarkBlackbox( + smc.originalPositionFor({ + line: testMapping.generatedLine, + column: testMapping.generatedColumn + }) + ); }, - function () { + function() { smc.destroy(); } ); }, "parse.and.iterate": () => { - return benchmark( - noop, - async function () { - const smc = await new sourceMap.SourceMapConsumer(testSourceMap); - - let maxLine = 0; - let maxCol = 0; - smc.eachMapping(m => { - maxLine = Math.max(maxLine, m.generatedLine); - maxLine = Math.max(maxLine, m.originalLine); - maxCol = Math.max(maxCol, m.generatedColumn); - maxCol = Math.max(maxCol, m.originalColumn); - }); - benchmarkBlackbox(maxLine); - benchmarkBlackbox(maxCol); - - smc.destroy(); - } - ); + return benchmark(noop, async function() { + const smc = await new sourceMap.SourceMapConsumer(testSourceMap); + + let maxLine = 0; + let maxCol = 0; + smc.eachMapping(m => { + maxLine = Math.max(maxLine, m.generatedLine); + maxLine = Math.max(maxLine, m.originalLine); + maxCol = Math.max(maxCol, m.generatedColumn); + maxCol = Math.max(maxCol, m.originalColumn); + }); + benchmarkBlackbox(maxLine); + benchmarkBlackbox(maxCol); + + smc.destroy(); + }); }, "iterate.already.parsed": () => { let smc; return benchmark( - async function () { + async function() { smc = await new sourceMap.SourceMapConsumer(testSourceMap); }, - async function () { + async function() { let maxLine = 0; let maxCol = 0; smc.eachMapping(m => { @@ -199,7 +204,7 @@ var benchmarks = { benchmarkBlackbox(maxLine); benchmarkBlackbox(maxCol); }, - function () { + function() { smc.destroy(); } ); diff --git a/bench/package.json b/bench/package.json new file mode 100644 index 00000000..7305b72a --- /dev/null +++ b/bench/package.json @@ -0,0 +1,11 @@ +{ + "name": "source-map-internal-benchmark", + "private": true, + "scripts": { + "build": "webpack" + }, + "dependencies": { + "webpack": "^4.9.1", + "webpack-cli": "^3.1" + } +} \ No newline at end of file diff --git a/bench/webpack.config.js b/bench/webpack.config.js new file mode 100644 index 00000000..aa4a7787 --- /dev/null +++ b/bench/webpack.config.js @@ -0,0 +1,17 @@ +const path = require("path"); +const distDir = path.join(__dirname, "dist"); + +module.exports = { + context: path.join(__dirname, ".."), + entry: "./source-map.js", + mode: "production", + optimization: { + minimize: false, + }, + output: { + path: distDir, + filename: "source-map.js", + library: "sourceMap", + libraryTarget: "umd", + }, +}; diff --git a/dist/source-map.js b/dist/source-map.js deleted file mode 100644 index 16b740ce..00000000 --- a/dist/source-map.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n(require("path"),require("fs")):"function"==typeof define&&define.amd?define(["path","fs"],n):"object"==typeof exports?exports.sourceMap=n(require("path"),require("fs")):e.sourceMap=n(e.path,e.fs)}(window,function(e,n){return function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=13)}([function(e,n){n.getArg=function(e,n,t){if(n in e)return e[n];if(3===arguments.length)return t;throw new Error('"'+n+'" is a required argument.')};const t=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,r=/^data:.+\,.+$/;function o(e){const n=e.match(t);return n?{scheme:n[1],auth:n[2],host:n[3],port:n[4],path:n[5]}:null}function i(e){let n="";return e.scheme&&(n+=e.scheme+":"),n+="//",e.auth&&(n+=e.auth+"@"),e.host&&(n+=e.host),e.port&&(n+=":"+e.port),e.path&&(n+=e.path),n}n.urlParse=o,n.urlGenerate=i;const s=32;const l=function(e){const n=[];return function(t){for(let e=0;es&&n.pop(),r}}(function(e){let t=e;const r=o(e);if(r){if(!r.path)return e;t=r.path}const s=n.isAbsolute(t),l=[];let a=0,u=0;for(;;){if(a=u,-1===(u=t.indexOf("/",a))){l.push(t.slice(a));break}for(l.push(t.slice(a,u));u=0;u--){const e=l[u];"."===e?l.splice(u,1):".."===e?c++:c>0&&(""===e?(l.splice(u+1,c),c=0):(l.splice(u,2),c--))}return""===(t=l.join("/"))&&(t=s?"/":"."),r?(r.path=t,i(r)):t});function a(e,n){""===e&&(e="."),""===n&&(n=".");const t=o(n),s=o(e);if(s&&(e=s.path||"/"),t&&!t.scheme)return s&&(t.scheme=s.scheme),i(t);if(t||n.match(r))return n;if(s&&!s.host&&!s.path)return s.host=n,i(s);const a="/"===n.charAt(0)?n:l(e.replace(/\/+$/,"")+"/"+n);return s?(s.path=a,i(s)):a}n.normalize=l,n.join=a,n.isAbsolute=function(e){return"/"===e.charAt(0)||t.test(e)},n.relative=function(e,n){""===e&&(e="."),e=e.replace(/\/$/,"");let t=0;for(;0!==n.indexOf(e+"/");){const r=e.lastIndexOf("/");if(r<0)return n;if((e=e.slice(0,r)).match(/^([^\/]+:\/)?\/*$/))return n;++t}return Array(t+1).join("../")+n.substr(e.length+1)};const u=!("__proto__"in Object.create(null));function c(e){return e}function g(e){if(!e)return!1;const n=e.length;if(n<9)return!1;if(95!==e.charCodeAt(n-1)||95!==e.charCodeAt(n-2)||111!==e.charCodeAt(n-3)||116!==e.charCodeAt(n-4)||111!==e.charCodeAt(n-5)||114!==e.charCodeAt(n-6)||112!==e.charCodeAt(n-7)||95!==e.charCodeAt(n-8)||95!==e.charCodeAt(n-9))return!1;for(let t=n-10;t>=0;t--)if(36!==e.charCodeAt(t))return!1;return!0}function p(e,n){return e===n?0:null===e?1:null===n?-1:e>n?1:-1}n.toSetString=u?c:function(e){return g(e)?"$"+e:e},n.fromSetString=u?c:function(e){return g(e)?e.slice(1):e},n.compareByOriginalPositions=function(e,n,t){let r=p(e.source,n.source);return 0!==r?r:0!=(r=e.originalLine-n.originalLine)?r:0!=(r=e.originalColumn-n.originalColumn)||t?r:0!=(r=e.generatedColumn-n.generatedColumn)?r:0!=(r=e.generatedLine-n.generatedLine)?r:p(e.name,n.name)},n.compareByGeneratedPositionsDeflated=function(e,n,t){let r=e.generatedLine-n.generatedLine;return 0!==r?r:0!=(r=e.generatedColumn-n.generatedColumn)||t?r:0!==(r=p(e.source,n.source))?r:0!=(r=e.originalLine-n.originalLine)?r:0!=(r=e.originalColumn-n.originalColumn)?r:p(e.name,n.name)},n.compareByGeneratedPositionsInflated=function(e,n){let t=e.generatedLine-n.generatedLine;return 0!==t?t:0!=(t=e.generatedColumn-n.generatedColumn)?t:0!==(t=p(e.source,n.source))?t:0!=(t=e.originalLine-n.originalLine)?t:0!=(t=e.originalColumn-n.originalColumn)?t:p(e.name,n.name)},n.parseSourceMapInput=function(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))},n.computeSourceURL=function(e,n,t){if(n=n||"",e&&("/"!==e[e.length-1]&&"/"!==n[0]&&(e+="/"),n=e+n),t){const e=o(t);if(!e)throw new Error("sourceMapURL could not be parsed");if(e.path){const n=e.path.lastIndexOf("/");n>=0&&(e.path=e.path.substring(0,n+1))}n=a(i(e),n)}return l(n)}},function(e,n,t){(function(n){if(function(){return"undefined"!=typeof window&&this===window}.call()){let n=null;e.exports=function(){if("string"==typeof n)return fetch(n).then(e=>e.arrayBuffer());if(n instanceof ArrayBuffer)return Promise.resolve(n);throw new Error("You must provide the string URL or ArrayBuffer contents of lib/mappings.wasm by calling SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) before using SourceMapConsumer")},e.exports.initialize=(e=>n=e)}else{const r=t(8),o=t(7);e.exports=function(){return new Promise((e,t)=>{const i=o.join(n,"mappings.wasm");r.readFile(i,null,(n,r)=>{n?t(n):e(r.buffer)})})},e.exports.initialize=(e=>{console.debug("SourceMapConsumer.initialize is a no-op when running in node.js")})}}).call(this,"/")},function(e,n){class t{constructor(){this._array=[],this._set=new Map}static fromArray(e,n){const r=new t;for(let t=0,o=e.length;t=0)return n;throw new Error('"'+e+'" is not in the set.')}at(e){if(e>=0&&e>>=5)>0&&(n|=32),t+=r.encode(n)}while(o>0);return t}},function(e,n,t){const r=t(3),o=t(0),i=t(2).ArraySet,s=t(11).MappingList;class l{constructor(e){e||(e={}),this._file=o.getArg(e,"file",null),this._sourceRoot=o.getArg(e,"sourceRoot",null),this._skipValidation=o.getArg(e,"skipValidation",!1),this._sources=new i,this._names=new i,this._mappings=new s,this._sourcesContents=null}static fromSourceMap(e){const n=e.sourceRoot,t=new l({file:e.file,sourceRoot:n});return e.eachMapping(function(e){const r={generated:{line:e.generatedLine,column:e.generatedColumn}};null!=e.source&&(r.source=e.source,null!=n&&(r.source=o.relative(n,r.source)),r.original={line:e.originalLine,column:e.originalColumn},null!=e.name&&(r.name=e.name)),t.addMapping(r)}),e.sources.forEach(function(r){let i=r;null!==n&&(i=o.relative(n,r)),t._sources.has(i)||t._sources.add(i);const s=e.sourceContentFor(r);null!=s&&t.setSourceContent(r,s)}),t}addMapping(e){const n=o.getArg(e,"generated"),t=o.getArg(e,"original",null);let r=o.getArg(e,"source",null),i=o.getArg(e,"name",null);this._skipValidation||this._validateMapping(n,t,r,i),null!=r&&(r=String(r),this._sources.has(r)||this._sources.add(r)),null!=i&&(i=String(i),this._names.has(i)||this._names.add(i)),this._mappings.add({generatedLine:n.line,generatedColumn:n.column,originalLine:null!=t&&t.line,originalColumn:null!=t&&t.column,source:r,name:i})}setSourceContent(e,n){let t=e;null!=this._sourceRoot&&(t=o.relative(this._sourceRoot,t)),null!=n?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[o.toSetString(t)]=n):this._sourcesContents&&(delete this._sourcesContents[o.toSetString(t)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))}applySourceMap(e,n,t){let r=n;if(null==n){if(null==e.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=e.file}const s=this._sourceRoot;null!=s&&(r=o.relative(s,r));const l=this._mappings.toArray().length>0?new i:this._sources,a=new i;this._mappings.unsortedForEach(function(n){if(n.source===r&&null!=n.originalLine){const r=e.originalPositionFor({line:n.originalLine,column:n.originalColumn});null!=r.source&&(n.source=r.source,null!=t&&(n.source=o.join(t,n.source)),null!=s&&(n.source=o.relative(s,n.source)),n.originalLine=r.line,n.originalColumn=r.column,null!=r.name&&(n.name=r.name))}const i=n.source;null==i||l.has(i)||l.add(i);const u=n.name;null==u||a.has(u)||a.add(u)},this),this._sources=l,this._names=a,e.sources.forEach(function(n){const r=e.sourceContentFor(n);null!=r&&(null!=t&&(n=o.join(t,n)),null!=s&&(n=o.relative(s,n)),this.setSourceContent(n,r))},this)}_validateMapping(e,n,t,r){if(n&&"number"!=typeof n.line&&"number"!=typeof n.column)throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!n&&!t&&!r);else if(!(e&&"line"in e&&"column"in e&&n&&"line"in n&&"column"in n&&e.line>0&&e.column>=0&&n.line>0&&n.column>=0&&t))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:t,original:n,name:r}))}_serializeMappings(){let e,n,t,i,s=0,l=1,a=0,u=0,c=0,g=0,p="";const h=this._mappings.toArray();for(let m=0,d=h.length;m0){if(!o.compareByGeneratedPositionsInflated(n,h[m-1]))continue;e+=","}e+=r.encode(n.generatedColumn-s),s=n.generatedColumn,null!=n.source&&(i=this._sources.indexOf(n.source),e+=r.encode(i-g),g=i,e+=r.encode(n.originalLine-1-u),u=n.originalLine-1,e+=r.encode(n.originalColumn-a),a=n.originalColumn,null!=n.name&&(t=this._names.indexOf(n.name),e+=r.encode(t-c),c=t)),p+=e}return p}_generateSourcesContent(e,n){return e.map(function(e){if(!this._sourcesContents)return null;null!=n&&(e=o.relative(n,e));const t=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,t)?this._sourcesContents[t]:null},this)}toJSON(){const e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e}toString(){return JSON.stringify(this.toJSON())}}l.prototype._version=3,n.SourceMapGenerator=l},function(e,n,t){const r=t(4).SourceMapGenerator,o=t(0),i=/(\r?\n)/,s=10,l="$$$isSourceNode$$$";class a{constructor(e,n,t,r,o){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==n?null:n,this.source=null==t?null:t,this.name=null==o?null:o,this[l]=!0,null!=r&&this.add(r)}static fromStringWithSourceMap(e,n,t){const r=new a,s=e.split(i);let l=0;const u=function(){return e()+(e()||"");function e(){return l=0;n--)this.prepend(e[n]);else{if(!e[l]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this}walk(e){let n;for(let t=0,r=this.children.length;t0){for(n=[],t=0;tWebAssembly.instantiate(n,{env:{mapping_callback(n,t,r,o,i,s,l,a,u,c){const g=new function(){this.generatedLine=0,this.generatedColumn=0,this.lastGeneratedColumn=null,this.source=null,this.originalLine=null,this.originalColumn=null,this.name=null};g.generatedLine=n+1,g.generatedColumn=t,r&&(g.lastGeneratedColumn=o-1),i&&(g.source=s,g.originalLine=l+1,g.originalColumn=a,u&&(g.name=c)),e[e.length-1](g)},start_all_generated_locations_for(){console.time("all_generated_locations_for")},end_all_generated_locations_for(){console.timeEnd("all_generated_locations_for")},start_compute_column_spans(){console.time("compute_column_spans")},end_compute_column_spans(){console.timeEnd("compute_column_spans")},start_generated_location_for(){console.time("generated_location_for")},end_generated_location_for(){console.timeEnd("generated_location_for")},start_original_location_for(){console.time("original_location_for")},end_original_location_for(){console.timeEnd("original_location_for")},start_parse_mappings(){console.time("parse_mappings")},end_parse_mappings(){console.timeEnd("parse_mappings")},start_sort_by_generated_location(){console.time("sort_by_generated_location")},end_sort_by_generated_location(){console.timeEnd("sort_by_generated_location")},start_sort_by_original_location(){console.time("sort_by_original_location")},end_sort_by_original_location(){console.timeEnd("sort_by_original_location")}}})).then(n=>({exports:n.instance.exports,withMappingCallback:(n,t)=>{e.push(n);try{t()}finally{e.pop()}}})).then(null,e=>{throw o=null,e})}},function(n,t){n.exports=e},function(e,t){e.exports=n},function(e,n){n.GREATEST_LOWER_BOUND=1,n.LEAST_UPPER_BOUND=2,n.search=function(e,t,r,o){if(0===t.length)return-1;let i=function e(t,r,o,i,s,l){const a=Math.floor((r-t)/2)+t,u=s(o,i[a],!0);return 0===u?a:u>0?r-a>1?e(a,r,o,i,s,l):l==n.LEAST_UPPER_BOUND?r1?e(t,a,o,i,s,l):l==n.LEAST_UPPER_BOUND?a:t<0?-1:t}(-1,t.length,e,t,r,o||n.GREATEST_LOWER_BOUND);if(i<0)return-1;for(;i-1>=0&&0===r(t[i],t[i-1],!0);)--i;return i}},function(e,n,t){const r=t(0),o=t(9),i=t(2).ArraySet,s=(t(3),t(1)),l=t(6),a=Symbol("smcInternal");class u{constructor(e,n){return e==a?Promise.resolve(this):function(e,n){let t=e;"string"==typeof e&&(t=r.parseSourceMapInput(e));const o=null!=t.sections?new g(t,n):new c(t,n);return Promise.resolve(o)}(e,n)}static initialize(e){s.initialize(e["lib/mappings.wasm"])}static fromSourceMap(e,n){return function(e,n){return c.fromSourceMap(e,n)}(e,n)}static async with(e,n,t){const r=await new u(e,n);try{return await t(r)}finally{r.destroy()}}_parseMappings(e,n){throw new Error("Subclasses must implement _parseMappings")}eachMapping(e,n,t){throw new Error("Subclasses must implement eachMapping")}allGeneratedPositionsFor(e){throw new Error("Subclasses must implement allGeneratedPositionsFor")}destroy(){throw new Error("Subclasses must implement destroy")}}u.prototype._version=3,u.GENERATED_ORDER=1,u.ORIGINAL_ORDER=2,u.GREATEST_LOWER_BOUND=1,u.LEAST_UPPER_BOUND=2,n.SourceMapConsumer=u;class c extends u{constructor(e,n){return super(a).then(t=>{let o=e;"string"==typeof e&&(o=r.parseSourceMapInput(e));const s=r.getArg(o,"version");let a=r.getArg(o,"sources");const u=r.getArg(o,"names",[]);let c=r.getArg(o,"sourceRoot",null);const g=r.getArg(o,"sourcesContent",null),p=r.getArg(o,"mappings"),h=r.getArg(o,"file",null);if(s!=t._version)throw new Error("Unsupported version: "+s);return c&&(c=r.normalize(c)),a=a.map(String).map(r.normalize).map(function(e){return c&&r.isAbsolute(c)&&r.isAbsolute(e)?r.relative(c,e):e}),t._names=i.fromArray(u.map(String),!0),t._sources=i.fromArray(a,!0),t._absoluteSources=t._sources.toArray().map(function(e){return r.computeSourceURL(c,e,n)}),t.sourceRoot=c,t.sourcesContent=g,t._mappings=p,t._sourceMapURL=n,t.file=h,t._computedColumnSpans=!1,t._mappingsPtr=0,t._wasm=null,l().then(e=>(t._wasm=e,t))})}_findSourceIndex(e){let n=e;if(null!=this.sourceRoot&&(n=r.relative(this.sourceRoot,n)),this._sources.has(n))return this._sources.indexOf(n);for(let n=0;n{null!==n.source&&(n.source=this._sources.at(n.source),n.source=r.computeSourceURL(s,n.source,this._sourceMapURL),null!==n.name&&(n.name=this._names.at(n.name))),e.call(o,n)},()=>{switch(i){case u.GENERATED_ORDER:this._wasm.exports.by_generated_location(this._getMappingsPtr());break;case u.ORIGINAL_ORDER:this._wasm.exports.by_original_location(this._getMappingsPtr());break;default:throw new Error("Unknown order of iteration.")}})}allGeneratedPositionsFor(e){let n=r.getArg(e,"source");const t=r.getArg(e,"line"),o=e.column||0;if((n=this._findSourceIndex(n))<0)return[];if(t<1)throw new Error("Line numbers must be >= 1");if(o<0)throw new Error("Column numbers must be >= 0");const i=[];return this._wasm.withMappingCallback(e=>{let n=e.lastGeneratedColumn;this._computedColumnSpans&&null===n&&(n=1/0),i.push({line:e.generatedLine,column:e.generatedColumn,lastColumn:n})},()=>{this._wasm.exports.all_generated_locations_for(this._getMappingsPtr(),n,t-1,"column"in e,o)}),i}destroy(){0!==this._mappingsPtr&&(this._wasm.exports.free_mappings(this._mappingsPtr),this._mappingsPtr=0)}computeColumnSpans(){this._computedColumnSpans||(this._wasm.exports.compute_column_spans(this._getMappingsPtr()),this._computedColumnSpans=!0)}originalPositionFor(e){const n={generatedLine:r.getArg(e,"line"),generatedColumn:r.getArg(e,"column")};if(n.generatedLine<1)throw new Error("Line numbers must be >= 1");if(n.generatedColumn<0)throw new Error("Column numbers must be >= 0");let t,o=r.getArg(e,"bias",u.GREATEST_LOWER_BOUND);if(null==o&&(o=u.GREATEST_LOWER_BOUND),this._wasm.withMappingCallback(e=>t=e,()=>{this._wasm.exports.original_location_for(this._getMappingsPtr(),n.generatedLine-1,n.generatedColumn,o)}),t&&t.generatedLine===n.generatedLine){let e=r.getArg(t,"source",null);null!==e&&(e=this._sources.at(e),e=r.computeSourceURL(this.sourceRoot,e,this._sourceMapURL));let n=r.getArg(t,"name",null);return null!==n&&(n=this._names.at(n)),{source:e,line:r.getArg(t,"originalLine",null),column:r.getArg(t,"originalColumn",null),name:n}}return{source:null,line:null,column:null,name:null}}hasContentsOfAllSources(){return!!this.sourcesContent&&(this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(e){return null==e}))}sourceContentFor(e,n){if(!this.sourcesContent)return null;const t=this._findSourceIndex(e);if(t>=0)return this.sourcesContent[t];let o,i=e;if(null!=this.sourceRoot&&(i=r.relative(this.sourceRoot,i)),null!=this.sourceRoot&&(o=r.urlParse(this.sourceRoot))){const e=i.replace(/^file:\/\//,"");if("file"==o.scheme&&this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];if((!o.path||"/"==o.path)&&this._sources.has("/"+i))return this.sourcesContent[this._sources.indexOf("/"+i)]}if(n)return null;throw new Error('"'+i+'" is not in the SourceMap.')}generatedPositionFor(e){let n=r.getArg(e,"source");if((n=this._findSourceIndex(n))<0)return{line:null,column:null,lastColumn:null};const t={source:n,originalLine:r.getArg(e,"line"),originalColumn:r.getArg(e,"column")};if(t.originalLine<1)throw new Error("Line numbers must be >= 1");if(t.originalColumn<0)throw new Error("Column numbers must be >= 0");let o,i=r.getArg(e,"bias",u.GREATEST_LOWER_BOUND);if(null==i&&(i=u.GREATEST_LOWER_BOUND),this._wasm.withMappingCallback(e=>o=e,()=>{this._wasm.exports.generated_location_for(this._getMappingsPtr(),t.source,t.originalLine-1,t.originalColumn,i)}),o&&o.source===t.source){let e=o.lastGeneratedColumn;return this._computedColumnSpans&&null===e&&(e=1/0),{line:r.getArg(o,"generatedLine",null),column:r.getArg(o,"generatedColumn",null),lastColumn:e}}return{line:null,column:null,lastColumn:null}}}c.prototype.consumer=u,n.BasicSourceMapConsumer=c;class g extends u{constructor(e,n){return super(a).then(t=>{let o=e;"string"==typeof e&&(o=r.parseSourceMapInput(e));const s=r.getArg(o,"version"),l=r.getArg(o,"sections");if(s!=t._version)throw new Error("Unsupported version: "+s);t._sources=new i,t._names=new i,t.__generatedMappings=null,t.__originalMappings=null,t.__generatedMappingsUnsorted=null,t.__originalMappingsUnsorted=null;let a={line:-1,column:0};return Promise.all(l.map(e=>{if(e.url)throw new Error("Support for url field in sections not implemented.");const t=r.getArg(e,"offset"),o=r.getArg(t,"line"),i=r.getArg(t,"column");if(o({generatedOffset:{generatedLine:o+1,generatedColumn:i+1},consumer:e}))})).then(e=>(t._sections=e,t))})}get _generatedMappings(){return this.__generatedMappings||this._sortGeneratedMappings(),this.__generatedMappings}get _originalMappings(){return this.__originalMappings||this._sortOriginalMappings(),this.__originalMappings}get _generatedMappingsUnsorted(){return this.__generatedMappingsUnsorted||this._parseMappings(this._mappings,this.sourceRoot),this.__generatedMappingsUnsorted}get _originalMappingsUnsorted(){return this.__originalMappingsUnsorted||this._parseMappings(this._mappings,this.sourceRoot),this.__originalMappingsUnsorted}_sortGeneratedMappings(){const e=this._generatedMappingsUnsorted;e.sort(r.compareByGeneratedPositionsDeflated),this.__generatedMappings=e}_sortOriginalMappings(){const e=this._originalMappingsUnsorted;e.sort(r.compareByOriginalPositions),this.__originalMappings=e}get sources(){const e=[];for(let n=0;ni.push(e));for(let e=0;e= 1");if(t.originalColumn<0)throw new Error("Column numbers must be >= 0");const i=[];let s=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",r.compareByOriginalPositions,o.LEAST_UPPER_BOUND);if(s>=0){let t=this._originalMappings[s];if(void 0===e.column){const e=t.originalLine;for(;t&&t.originalLine===e;){let e=t.lastGeneratedColumn;this._computedColumnSpans&&null===e&&(e=1/0),i.push({line:r.getArg(t,"generatedLine",null),column:r.getArg(t,"generatedColumn",null),lastColumn:e}),t=this._originalMappings[++s]}}else{const e=t.originalColumn;for(;t&&t.originalLine===n&&t.originalColumn==e;){let e=t.lastGeneratedColumn;this._computedColumnSpans&&null===e&&(e=1/0),i.push({line:r.getArg(t,"generatedLine",null),column:r.getArg(t,"generatedColumn",null),lastColumn:e}),t=this._originalMappings[++s]}}}return i}destroy(){for(let e=0;et||o==t&&s>=i||r.compareByGeneratedPositionsInflated(e,n)<=0}(this._last,e)?(this._sorted=!1,this._array.push(e)):(this._last=e,this._array.push(e))}toArray(){return this._sorted||(this._array.sort(r.compareByGeneratedPositionsInflated),this._sorted=!0),this._array}}},function(e,n){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");n.encode=function(e){if(0<=e&&e= 0) { - return idx; + return idx; } throw new Error('"' + aStr + '" is not in the set.'); } diff --git a/lib/base64-vlq.js b/lib/base64-vlq.js index fc1049c8..2daed1eb 100644 --- a/lib/base64-vlq.js +++ b/lib/base64-vlq.js @@ -67,24 +67,7 @@ const VLQ_CONTINUATION_BIT = VLQ_BASE; * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) */ function toVLQSigned(aValue) { - return aValue < 0 - ? ((-aValue) << 1) + 1 - : (aValue << 1) + 0; -} - -/** - * Converts to a two-complement value from a value where the sign bit is - * placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - */ -// eslint-disable-next-line no-unused-vars -function fromVLQSigned(aValue) { - const isNegative = (aValue & 1) === 1; - const shifted = aValue >> 1; - return isNegative - ? -shifted - : shifted; + return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0; } /** diff --git a/lib/base64.js b/lib/base64.js index b9ca3199..939abc8e 100644 --- a/lib/base64.js +++ b/lib/base64.js @@ -5,12 +5,13 @@ * http://opensource.org/licenses/BSD-3-Clause */ -const intToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""); +const intToCharMap = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""); /** * Encode an integer in the range of 0 to 63 to a single base 64 digit. */ -exports.encode = function(number) { +exports.encode = function (number) { if (0 <= number && number < intToCharMap.length) { return intToCharMap[number]; } diff --git a/lib/binary-search.js b/lib/binary-search.js index d6f898ea..db65ccd1 100644 --- a/lib/binary-search.js +++ b/lib/binary-search.js @@ -45,7 +45,7 @@ function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { // The exact needle element was not found in this haystack. Determine if // we are in termination case (3) or (2) and return the appropriate thing. - if (aBias == exports.LEAST_UPPER_BOUND) { + if (aBias === exports.LEAST_UPPER_BOUND) { return aHigh < aHaystack.length ? aHigh : -1; } return mid; @@ -87,13 +87,19 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { return -1; } - let index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, - aCompare, aBias || exports.GREATEST_LOWER_BOUND); + let index = recursiveSearch( + -1, + aHaystack.length, + aNeedle, + aHaystack, + aCompare, + aBias || exports.GREATEST_LOWER_BOUND + ); if (index < 0) { return -1; } - // We have found either the exact element, or the next-closest element than + // We have found either the exact element, or the next-closest element to // the one we are searching for. However, there may be more than one such // element. Make sure we always return the smallest of these. while (index - 1 >= 0) { diff --git a/lib/mapping-list.js b/lib/mapping-list.js index 70568610..ece3c2cc 100644 --- a/lib/mapping-list.js +++ b/lib/mapping-list.js @@ -17,8 +17,11 @@ function generatedPositionAfter(mappingA, mappingB) { const lineB = mappingB.generatedLine; const columnA = mappingA.generatedColumn; const columnB = mappingB.generatedColumn; - return lineB > lineA || lineB == lineA && columnB >= columnA || - util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + return ( + lineB > lineA || + (lineB == lineA && columnB >= columnA) || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0 + ); } /** @@ -31,7 +34,7 @@ class MappingList { this._array = []; this._sorted = true; // Serves as infimum - this._last = {generatedLine: -1, generatedColumn: 0}; + this._last = { generatedLine: -1, generatedColumn: 0 }; } /** diff --git a/lib/mappings.wasm b/lib/mappings.wasm index 35153707..cdcc2958 100644 Binary files a/lib/mappings.wasm and b/lib/mappings.wasm differ diff --git a/lib/read-wasm-browser.js b/lib/read-wasm-browser.js new file mode 100644 index 00000000..a4fb29c2 --- /dev/null +++ b/lib/read-wasm-browser.js @@ -0,0 +1,23 @@ +"use strict"; + +let mappingsWasm = null; + +module.exports = function readWasm() { + if (typeof mappingsWasm === "string") { + return fetch(mappingsWasm).then(response => response.arrayBuffer()); + } + if (mappingsWasm instanceof ArrayBuffer) { + return Promise.resolve(mappingsWasm); + } + + throw new Error( + "You must provide the string URL or ArrayBuffer contents " + + "of lib/mappings.wasm by calling " + + "SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " + + "before using SourceMapConsumer" + ); +}; + +module.exports.initialize = input => { + mappingsWasm = input; +}; diff --git a/lib/read-wasm.js b/lib/read-wasm.js index e81c1772..2ce01a75 100644 --- a/lib/read-wasm.js +++ b/lib/read-wasm.js @@ -1,49 +1,27 @@ -/* Determine browser vs node environment by testing the default top level context. Solution courtesy of: https://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser */ -const isBrowserEnvironment = (function() { - // eslint-disable-next-line no-undef - return (typeof window !== "undefined") && (this === window); -}).call(); +"use strict"; -if (isBrowserEnvironment) { - // Web version of reading a wasm file into an array buffer. +// Note: This file is replaced with "read-wasm-browser.js" when this module is +// bundled with a packager that takes package.json#browser fields into account. - let mappingsWasm = null; +const fs = require("fs"); +const path = require("path"); - module.exports = function readWasm() { - if (typeof mappingsWasm === "string") { - return fetch(mappingsWasm) - .then(response => response.arrayBuffer()); - } - if (mappingsWasm instanceof ArrayBuffer) { - return Promise.resolve(mappingsWasm); - } - throw new Error("You must provide the string URL or ArrayBuffer contents " + - "of lib/mappings.wasm by calling " + - "SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " + - "before using SourceMapConsumer"); - }; +module.exports = function readWasm() { + return new Promise((resolve, reject) => { + const wasmPath = path.join(__dirname, "mappings.wasm"); + fs.readFile(wasmPath, null, (error, data) => { + if (error) { + reject(error); + return; + } - module.exports.initialize = input => mappingsWasm = input; -} else { - // Node version of reading a wasm file into an array buffer. - const fs = require("fs"); - const path = require("path"); - - module.exports = function readWasm() { - return new Promise((resolve, reject) => { - const wasmPath = path.join(__dirname, "mappings.wasm"); - fs.readFile(wasmPath, null, (error, data) => { - if (error) { - reject(error); - return; - } - - resolve(data.buffer); - }); + resolve(data.buffer); }); - }; + }); +}; - module.exports.initialize = _ => { - console.debug("SourceMapConsumer.initialize is a no-op when running in node.js"); - }; -} +module.exports.initialize = _ => { + console.debug( + "SourceMapConsumer.initialize is a no-op when running in node.js" + ); +}; diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js index 9aaf92f5..7381a668 100644 --- a/lib/source-map-consumer.js +++ b/lib/source-map-consumer.js @@ -73,15 +73,6 @@ class SourceMapConsumer { } } - /** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). - */ - _parseMappings(aStr, aSourceRoot) { - throw new Error("Subclasses must implement _parseMappings"); - } - /** * Iterate over each mapping between an original source/line/column and a * generated line/column in this source map. @@ -188,14 +179,19 @@ class BasicSourceMapConsumer extends SourceMapConsumer { } const version = util.getArg(sourceMap, "version"); - let sources = util.getArg(sourceMap, "sources"); + const sources = util.getArg(sourceMap, "sources").map(String); // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which // requires the array) to play nice here. const names = util.getArg(sourceMap, "names", []); - let sourceRoot = util.getArg(sourceMap, "sourceRoot", null); + const sourceRoot = util.getArg(sourceMap, "sourceRoot", null); const sourcesContent = util.getArg(sourceMap, "sourcesContent", null); const mappings = util.getArg(sourceMap, "mappings"); const file = util.getArg(sourceMap, "file", null); + const x_google_ignoreList = util.getArg( + sourceMap, + "x_google_ignoreList", + null + ); // Once again, Sass deviates from the spec and supplies the version as a // string rather than a number, so we use loose equality checking here. @@ -203,25 +199,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { throw new Error("Unsupported version: " + version); } - if (sourceRoot) { - sourceRoot = util.normalize(sourceRoot); - } - - sources = sources - .map(String) - // Some source maps produce relative source paths like "./foo.js" instead of - // "foo.js". Normalize these first so that future comparisons will succeed. - // See bugzil.la/1090768. - .map(util.normalize) - // Always ensure that absolute sources are internally stored relative to - // the source root, if the source root is absolute. Not doing this would - // be particularly problematic when the source root is a prefix of the - // source (valid, but why??). See github issue #199 and bugzil.la/1188982. - .map(function(source) { - return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) - ? util.relative(sourceRoot, source) - : source; - }); + that._sourceLookupCache = new Map(); // Pass `true` below to allow duplicate names and sources. While source maps // are intended to be compressed and deduplicated, the TypeScript compiler @@ -230,15 +208,19 @@ class BasicSourceMapConsumer extends SourceMapConsumer { that._names = ArraySet.fromArray(names.map(String), true); that._sources = ArraySet.fromArray(sources, true); - that._absoluteSources = that._sources.toArray().map(function(s) { - return util.computeSourceURL(sourceRoot, s, aSourceMapURL); - }); + that._absoluteSources = ArraySet.fromArray( + that._sources.toArray().map(function (s) { + return util.computeSourceURL(sourceRoot, s, aSourceMapURL); + }), + true + ); that.sourceRoot = sourceRoot; that.sourcesContent = sourcesContent; that._mappings = mappings; that._sourceMapURL = aSourceMapURL; that.file = file; + that.x_google_ignoreList = x_google_ignoreList; that._computedColumnSpans = false; that._mappingsPtr = 0; @@ -256,23 +238,38 @@ class BasicSourceMapConsumer extends SourceMapConsumer { * found. */ _findSourceIndex(aSource) { - let relativeSource = aSource; - if (this.sourceRoot != null) { - relativeSource = util.relative(this.sourceRoot, relativeSource); + // In the most common usecases, we'll be constantly looking up the index for the same source + // files, so we cache the index lookup to avoid constantly recomputing the full URLs. + const cachedIndex = this._sourceLookupCache.get(aSource); + if (typeof cachedIndex === "number") { + return cachedIndex; } - if (this._sources.has(relativeSource)) { - return this._sources.indexOf(relativeSource); + // Treat the source as map-relative overall by default. + const sourceAsMapRelative = util.computeSourceURL( + null, + aSource, + this._sourceMapURL + ); + if (this._absoluteSources.has(sourceAsMapRelative)) { + const index = this._absoluteSources.indexOf(sourceAsMapRelative); + this._sourceLookupCache.set(aSource, index); + return index; } - // Maybe aSource is an absolute URL as returned by |sources|. In - // this case we can't simply undo the transform. - for (let i = 0; i < this._absoluteSources.length; ++i) { - if (this._absoluteSources[i] == aSource) { - return i; - } + // Fall back to treating the source as sourceRoot-relative. + const sourceAsSourceRootRelative = util.computeSourceURL( + this.sourceRoot, + aSource, + this._sourceMapURL + ); + if (this._absoluteSources.has(sourceAsSourceRootRelative)) { + const index = this._absoluteSources.indexOf(sourceAsSourceRootRelative); + this._sourceLookupCache.set(aSource, index); + return index; } + // To avoid this cache growing forever, we do not cache lookup misses. return -1; } @@ -290,12 +287,12 @@ class BasicSourceMapConsumer extends SourceMapConsumer { } get sources() { - return this._absoluteSources.slice(); + return this._absoluteSources.toArray(); } _getMappingsPtr() { if (this._mappingsPtr === 0) { - this._parseMappings(this._mappings, this.sourceRoot); + this._parseMappings(); } return this._mappingsPtr; @@ -306,11 +303,18 @@ class BasicSourceMapConsumer extends SourceMapConsumer { * query (the ordered arrays in the `this.__generatedMappings` and * `this.__originalMappings` properties). */ - _parseMappings(aStr, aSourceRoot) { + _parseMappings() { + const aStr = this._mappings; const size = aStr.length; - const mappingsBufPtr = this._wasm.exports.allocate_mappings(size); - const mappingsBuf = new Uint8Array(this._wasm.exports.memory.buffer, mappingsBufPtr, size); + // Interpret signed result of allocate_mappings as unsigned, otherwise + // addresses higher than 2GB will be negative. + const mappingsBufPtr = this._wasm.exports.allocate_mappings(size) >>> 0; + const mappingsBuf = new Uint8Array( + this._wasm.exports.memory.buffer, + mappingsBufPtr, + size + ); for (let i = 0; i < size; i++) { mappingsBuf[i] = aStr.charCodeAt(i); } @@ -321,10 +325,11 @@ class BasicSourceMapConsumer extends SourceMapConsumer { const error = this._wasm.exports.get_last_error(); let msg = `Error parsing mappings (code ${error}): `; - // XXX: keep these error codes in sync with `fitzgen/source-map-mappings`. + // XXX: keep these error codes in sync with `wasm-mappings`. switch (error) { case 1: - msg += "the mappings contained a negative line, column, source index, or name index"; + msg += + "the mappings contained a negative line, column, source index, or name index"; break; case 2: msg += "the mappings contained a number larger than 2**32"; @@ -349,31 +354,32 @@ class BasicSourceMapConsumer extends SourceMapConsumer { eachMapping(aCallback, aContext, aOrder) { const context = aContext || null; const order = aOrder || SourceMapConsumer.GENERATED_ORDER; - const sourceRoot = this.sourceRoot; this._wasm.withMappingCallback( mapping => { if (mapping.source !== null) { - mapping.source = this._sources.at(mapping.source); - mapping.source = util.computeSourceURL(sourceRoot, mapping.source, this._sourceMapURL); + mapping.source = this._absoluteSources.at(mapping.source); if (mapping.name !== null) { mapping.name = this._names.at(mapping.name); } } + if (this._computedColumnSpans && mapping.lastGeneratedColumn === null) { + mapping.lastGeneratedColumn = Infinity; + } aCallback.call(context, mapping); }, () => { switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - this._wasm.exports.by_generated_location(this._getMappingsPtr()); - break; - case SourceMapConsumer.ORIGINAL_ORDER: - this._wasm.exports.by_original_location(this._getMappingsPtr()); - break; - default: - throw new Error("Unknown order of iteration."); + case SourceMapConsumer.GENERATED_ORDER: + this._wasm.exports.by_generated_location(this._getMappingsPtr()); + break; + case SourceMapConsumer.ORIGINAL_ORDER: + this._wasm.exports.by_original_location(this._getMappingsPtr()); + break; + default: + throw new Error("Unknown order of iteration."); } } ); @@ -410,7 +416,8 @@ class BasicSourceMapConsumer extends SourceMapConsumer { column: m.generatedColumn, lastColumn, }); - }, () => { + }, + () => { this._wasm.exports.all_generated_locations_for( this._getMappingsPtr(), source, @@ -471,7 +478,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { originalPositionFor(aArgs) { const needle = { generatedLine: util.getArg(aArgs, "line"), - generatedColumn: util.getArg(aArgs, "column") + generatedColumn: util.getArg(aArgs, "column"), }; if (needle.generatedLine < 1) { @@ -482,27 +489,33 @@ class BasicSourceMapConsumer extends SourceMapConsumer { throw new Error("Column numbers must be >= 0"); } - let bias = util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND); + let bias = util.getArg( + aArgs, + "bias", + SourceMapConsumer.GREATEST_LOWER_BOUND + ); if (bias == null) { bias = SourceMapConsumer.GREATEST_LOWER_BOUND; } let mapping; - this._wasm.withMappingCallback(m => mapping = m, () => { - this._wasm.exports.original_location_for( - this._getMappingsPtr(), - needle.generatedLine - 1, - needle.generatedColumn, - bias - ); - }); + this._wasm.withMappingCallback( + m => (mapping = m), + () => { + this._wasm.exports.original_location_for( + this._getMappingsPtr(), + needle.generatedLine - 1, + needle.generatedColumn, + bias + ); + } + ); if (mapping) { if (mapping.generatedLine === needle.generatedLine) { let source = util.getArg(mapping, "source", null); if (source !== null) { - source = this._sources.at(source); - source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL); + source = this._absoluteSources.at(source); } let name = util.getArg(mapping, "name", null); @@ -514,7 +527,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { source, line: util.getArg(mapping, "originalLine", null), column: util.getArg(mapping, "originalColumn", null), - name + name, }; } } @@ -523,7 +536,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { source: null, line: null, column: null, - name: null + name: null, }; } @@ -535,8 +548,12 @@ class BasicSourceMapConsumer extends SourceMapConsumer { if (!this.sourcesContent) { return false; } - return this.sourcesContent.length >= this._sources.size() && - !this.sourcesContent.some(function(sc) { return sc == null; }); + return ( + this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { + return sc == null; + }) + ); } /** @@ -554,30 +571,6 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return this.sourcesContent[index]; } - let relativeSource = aSource; - if (this.sourceRoot != null) { - relativeSource = util.relative(this.sourceRoot, relativeSource); - } - - let url; - if (this.sourceRoot != null - && (url = util.urlParse(this.sourceRoot))) { - // XXX: file:// URIs and absolute paths lead to unexpected behavior for - // many users. We can help them out when they expect file:// URIs to - // behave like it would if they were running a local HTTP server. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. - const fileUriAbsPath = relativeSource.replace(/^file:\/\//, ""); - if (url.scheme == "file" - && this._sources.has(fileUriAbsPath)) { - return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]; - } - - if ((!url.path || url.path == "/") - && this._sources.has("/" + relativeSource)) { - return this.sourcesContent[this._sources.indexOf("/" + relativeSource)]; - } - } - // This function is used recursively from // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we // don't want to throw if we can't find the source - we just want to @@ -586,7 +579,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return null; } - throw new Error('"' + relativeSource + '" is not in the SourceMap.'); + throw new Error('"' + aSource + '" is not in the SourceMap.'); } /** @@ -619,14 +612,14 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return { line: null, column: null, - lastColumn: null + lastColumn: null, }; } const needle = { source, originalLine: util.getArg(aArgs, "line"), - originalColumn: util.getArg(aArgs, "column") + originalColumn: util.getArg(aArgs, "column"), }; if (needle.originalLine < 1) { @@ -637,21 +630,28 @@ class BasicSourceMapConsumer extends SourceMapConsumer { throw new Error("Column numbers must be >= 0"); } - let bias = util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND); + let bias = util.getArg( + aArgs, + "bias", + SourceMapConsumer.GREATEST_LOWER_BOUND + ); if (bias == null) { bias = SourceMapConsumer.GREATEST_LOWER_BOUND; } let mapping; - this._wasm.withMappingCallback(m => mapping = m, () => { - this._wasm.exports.generated_location_for( - this._getMappingsPtr(), - needle.source, - needle.originalLine - 1, - needle.originalColumn, - bias - ); - }); + this._wasm.withMappingCallback( + m => (mapping = m), + () => { + this._wasm.exports.generated_location_for( + this._getMappingsPtr(), + needle.source, + needle.originalLine - 1, + needle.originalColumn, + bias + ); + } + ); if (mapping) { if (mapping.source === needle.source) { @@ -670,7 +670,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return { line: null, column: null, - lastColumn: null + lastColumn: null, }; } } @@ -742,125 +742,56 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { throw new Error("Unsupported version: " + version); } - that._sources = new ArraySet(); - that._names = new ArraySet(); - that.__generatedMappings = null; - that.__originalMappings = null; - that.__generatedMappingsUnsorted = null; - that.__originalMappingsUnsorted = null; - let lastOffset = { line: -1, - column: 0 + column: 0, }; - return Promise.all(sections.map(s => { - if (s.url) { - // The url field will require support for asynchronicity. - // See https://github.com/mozilla/source-map/issues/16 - throw new Error("Support for url field in sections not implemented."); - } - const offset = util.getArg(s, "offset"); - const offsetLine = util.getArg(offset, "line"); - const offsetColumn = util.getArg(offset, "column"); - - if (offsetLine < lastOffset.line || - (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { - throw new Error("Section offsets must be ordered and non-overlapping."); - } - lastOffset = offset; - - const cons = new SourceMapConsumer(util.getArg(s, "map"), aSourceMapURL); - return cons.then(consumer => { - return { - generatedOffset: { - // The offset fields are 0-based, but we use 1-based indices when - // encoding/decoding from VLQ. - generatedLine: offsetLine + 1, - generatedColumn: offsetColumn + 1 - }, - consumer - }; - }); - })).then(s => { + return Promise.all( + sections.map(s => { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error( + "Support for url field in sections not implemented." + ); + } + const offset = util.getArg(s, "offset"); + const offsetLine = util.getArg(offset, "line"); + const offsetColumn = util.getArg(offset, "column"); + + if ( + offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column) + ) { + throw new Error( + "Section offsets must be ordered and non-overlapping." + ); + } + lastOffset = offset; + + const cons = new SourceMapConsumer( + util.getArg(s, "map"), + aSourceMapURL + ); + return cons.then(consumer => { + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1, + }, + consumer, + }; + }); + }) + ).then(s => { that._sections = s; return that; }); }); } - // `__generatedMappings` and `__originalMappings` are arrays that hold the - // parsed mapping coordinates from the source map's "mappings" attribute. They - // are lazily instantiated, accessed via the `_generatedMappings` and - // `_originalMappings` getters respectively, and we only parse the mappings - // and create these arrays once queried for a source location. We jump through - // these hoops because there can be many thousands of mappings, and parsing - // them is expensive, so we only want to do it if we must. - // - // Each object in the arrays is of the form: - // - // { - // generatedLine: The line number in the generated code, - // generatedColumn: The column number in the generated code, - // source: The path to the original source file that generated this - // chunk of code, - // originalLine: The line number in the original source that - // corresponds to this chunk of generated code, - // originalColumn: The column number in the original source that - // corresponds to this chunk of generated code, - // name: The name of the original symbol which generated this chunk of - // code. - // } - // - // All properties except for `generatedLine` and `generatedColumn` can be - // `null`. - // - // `_generatedMappings` is ordered by the generated positions. - // - // `_originalMappings` is ordered by the original positions. - get _generatedMappings() { - if (!this.__generatedMappings) { - this._sortGeneratedMappings(); - } - - return this.__generatedMappings; - } - - get _originalMappings() { - if (!this.__originalMappings) { - this._sortOriginalMappings(); - } - - return this.__originalMappings; - } - - get _generatedMappingsUnsorted() { - if (!this.__generatedMappingsUnsorted) { - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__generatedMappingsUnsorted; - } - - get _originalMappingsUnsorted() { - if (!this.__originalMappingsUnsorted) { - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__originalMappingsUnsorted; - } - - _sortGeneratedMappings() { - const mappings = this._generatedMappingsUnsorted; - mappings.sort(util.compareByGeneratedPositionsDeflated); - this.__generatedMappings = mappings; - } - - _sortOriginalMappings() { - const mappings = this._originalMappingsUnsorted; - mappings.sort(util.compareByOriginalPositions); - this.__originalMappings = mappings; - } - /** * The list of original sources. */ @@ -896,21 +827,29 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { originalPositionFor(aArgs) { const needle = { generatedLine: util.getArg(aArgs, "line"), - generatedColumn: util.getArg(aArgs, "column") + generatedColumn: util.getArg(aArgs, "column"), }; // Find the section containing the generated position we're trying to map // to an original position. - const sectionIndex = binarySearch.search(needle, this._sections, - function(aNeedle, section) { - const cmp = aNeedle.generatedLine - section.generatedOffset.generatedLine; + const sectionIndex = binarySearch.search( + needle, + this._sections, + function (aNeedle, section) { + const cmp = + aNeedle.generatedLine - section.generatedOffset.generatedLine; if (cmp) { return cmp; } - return (aNeedle.generatedColumn - - section.generatedOffset.generatedColumn); - }); + // The generated column is 0-based, but the section offset column is + // stored 1-based. + return ( + aNeedle.generatedColumn - + (section.generatedOffset.generatedColumn - 1) + ); + } + ); const section = this._sections[sectionIndex]; if (!section) { @@ -918,18 +857,18 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { source: null, line: null, column: null, - name: null + name: null, }; } return section.consumer.originalPositionFor({ - line: needle.generatedLine - - (section.generatedOffset.generatedLine - 1), - column: needle.generatedColumn - + line: needle.generatedLine - (section.generatedOffset.generatedLine - 1), + column: + needle.generatedColumn - (section.generatedOffset.generatedLine === needle.generatedLine - ? section.generatedOffset.generatedColumn - 1 - : 0), - bias: aArgs.bias + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias, }); } @@ -938,7 +877,7 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { * map, false otherwise. */ hasContentsOfAllSources() { - return this._sections.every(function(s) { + return this._sections.every(function (s) { return s.consumer.hasContentsOfAllSources(); }); } @@ -963,6 +902,16 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { throw new Error('"' + aSource + '" is not in the SourceMap.'); } + _findSectionIndex(source) { + for (let i = 0; i < this._sections.length; i++) { + const { consumer } = this._sections[i]; + if (consumer._findSourceIndex(source) !== -1) { + return i; + } + } + return -1; + } + /** * Returns the generated line and column information for the original source, * line, and column positions provided. The only argument is an object with @@ -982,230 +931,124 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { * The column number is 0-based. */ generatedPositionFor(aArgs) { - for (let i = 0; i < this._sections.length; i++) { - const section = this._sections[i]; - - // Only consider this section if the requested source is in the list of - // sources of the consumer. - if (section.consumer._findSourceIndex(util.getArg(aArgs, "source")) === -1) { - continue; + const index = this._findSectionIndex(util.getArg(aArgs, "source")); + const section = index >= 0 ? this._sections[index] : null; + const nextSection = + index >= 0 && index + 1 < this._sections.length + ? this._sections[index + 1] + : null; + + const generatedPosition = + section && section.consumer.generatedPositionFor(aArgs); + if (generatedPosition && generatedPosition.line !== null) { + const lineShift = section.generatedOffset.generatedLine - 1; + const columnShift = section.generatedOffset.generatedColumn - 1; + + if (generatedPosition.line === 1) { + generatedPosition.column += columnShift; + if (typeof generatedPosition.lastColumn === "number") { + generatedPosition.lastColumn += columnShift; + } } - const generatedPosition = section.consumer.generatedPositionFor(aArgs); - if (generatedPosition) { - const ret = { - line: generatedPosition.line + - (section.generatedOffset.generatedLine - 1), - column: generatedPosition.column + - (section.generatedOffset.generatedLine === generatedPosition.line - ? section.generatedOffset.generatedColumn - 1 - : 0) - }; - return ret; + + if ( + generatedPosition.lastColumn === Infinity && + nextSection && + generatedPosition.line === nextSection.generatedOffset.generatedLine + ) { + generatedPosition.lastColumn = + nextSection.generatedOffset.generatedColumn - 2; } + generatedPosition.line += lineShift; + + return generatedPosition; } return { line: null, - column: null + column: null, + lastColumn: null, }; } - /** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). - */ - _parseMappings(aStr, aSourceRoot) { - const generatedMappings = this.__generatedMappingsUnsorted = []; - const originalMappings = this.__originalMappingsUnsorted = []; - for (let i = 0; i < this._sections.length; i++) { - const section = this._sections[i]; - - const sectionMappings = []; - section.consumer.eachMapping(m => sectionMappings.push(m)); - - for (let j = 0; j < sectionMappings.length; j++) { - const mapping = sectionMappings[j]; - - // TODO: test if null is correct here. The original code used - // `source`, which would actually have gotten used as null because - // var's get hoisted. - // See: https://github.com/mozilla/source-map/issues/333 - let source = util.computeSourceURL(section.consumer.sourceRoot, null, this._sourceMapURL); - this._sources.add(source); - source = this._sources.indexOf(source); - - let name = null; - if (mapping.name) { - this._names.add(mapping.name); - name = this._names.indexOf(mapping.name); + allGeneratedPositionsFor(aArgs) { + const index = this._findSectionIndex(util.getArg(aArgs, "source")); + const section = index >= 0 ? this._sections[index] : null; + const nextSection = + index >= 0 && index + 1 < this._sections.length + ? this._sections[index + 1] + : null; + + if (!section) return []; + + return section.consumer + .allGeneratedPositionsFor(aArgs) + .map(generatedPosition => { + const lineShift = section.generatedOffset.generatedLine - 1; + const columnShift = section.generatedOffset.generatedColumn - 1; + + if (generatedPosition.line === 1) { + generatedPosition.column += columnShift; + if (typeof generatedPosition.lastColumn === "number") { + generatedPosition.lastColumn += columnShift; + } } - // The mappings coming from the consumer for the section have - // generated positions relative to the start of the section, so we - // need to offset them to be relative to the start of the concatenated - // generated file. - const adjustedMapping = { - source, - generatedLine: mapping.generatedLine + - (section.generatedOffset.generatedLine - 1), - generatedColumn: mapping.generatedColumn + - (section.generatedOffset.generatedLine === mapping.generatedLine - ? section.generatedOffset.generatedColumn - 1 - : 0), - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name - }; - - generatedMappings.push(adjustedMapping); - if (typeof adjustedMapping.originalLine === "number") { - originalMappings.push(adjustedMapping); + if ( + generatedPosition.lastColumn === Infinity && + nextSection && + generatedPosition.line === nextSection.generatedOffset.generatedLine + ) { + generatedPosition.lastColumn = + nextSection.generatedOffset.generatedColumn - 2; } - } - } - } - - eachMapping(aCallback, aContext, aOrder) { - const context = aContext || null; - const order = aOrder || SourceMapConsumer.GENERATED_ORDER; + generatedPosition.line += lineShift; - let mappings; - switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - mappings = this._generatedMappings; - break; - case SourceMapConsumer.ORIGINAL_ORDER: - mappings = this._originalMappings; - break; - default: - throw new Error("Unknown order of iteration."); - } - - const sourceRoot = this.sourceRoot; - mappings.map(function(mapping) { - let source = null; - if (mapping.source !== null) { - source = this._sources.at(mapping.source); - source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); - } - return { - source, - generatedLine: mapping.generatedLine, - generatedColumn: mapping.generatedColumn, - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name: mapping.name === null ? null : this._names.at(mapping.name) - }; - }, this).forEach(aCallback, context); - } - - /** - * Find the mapping that best matches the hypothetical "needle" mapping that - * we are searching for in the given "haystack" of mappings. - */ - _findMapping(aNeedle, aMappings, aLineName, - aColumnName, aComparator, aBias) { - // To return the position we are searching for, we must first find the - // mapping for the given position and then return the opposite position it - // points to. Because the mappings are sorted, we can use binary search to - // find the best mapping. - - if (aNeedle[aLineName] <= 0) { - throw new TypeError("Line must be greater than or equal to 1, got " - + aNeedle[aLineName]); - } - if (aNeedle[aColumnName] < 0) { - throw new TypeError("Column must be greater than or equal to 0, got " - + aNeedle[aColumnName]); - } - - return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + return generatedPosition; + }); } - allGeneratedPositionsFor(aArgs) { - const line = util.getArg(aArgs, "line"); - - // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping - // returns the index of the closest mapping less than the needle. By - // setting needle.originalColumn to 0, we thus find the last mapping for - // the given line, provided such a mapping exists. - const needle = { - source: util.getArg(aArgs, "source"), - originalLine: line, - originalColumn: util.getArg(aArgs, "column", 0) - }; - - needle.source = this._findSourceIndex(needle.source); - if (needle.source < 0) { - return []; - } - - if (needle.originalLine < 1) { - throw new Error("Line numbers must be >= 1"); - } - - if (needle.originalColumn < 0) { - throw new Error("Column numbers must be >= 0"); - } - - const mappings = []; - - let index = this._findMapping(needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions, - binarySearch.LEAST_UPPER_BOUND); - if (index >= 0) { - let mapping = this._originalMappings[index]; - - if (aArgs.column === undefined) { - const originalLine = mapping.originalLine; - - // Iterate until either we run out of mappings, or we run into - // a mapping for a different line than the one we found. Since - // mappings are sorted, this is guaranteed to find all mappings for - // the line we found. - while (mapping && mapping.originalLine === originalLine) { - let lastColumn = mapping.lastGeneratedColumn; - if (this._computedColumnSpans && lastColumn === null) { - lastColumn = Infinity; + eachMapping(aCallback, aContext, aOrder) { + this._sections.forEach((section, index) => { + const nextSection = + index + 1 < this._sections.length ? this._sections[index + 1] : null; + const { generatedOffset } = section; + + const lineShift = generatedOffset.generatedLine - 1; + const columnShift = generatedOffset.generatedColumn - 1; + + section.consumer.eachMapping( + function (mapping) { + if (mapping.generatedLine === 1) { + mapping.generatedColumn += columnShift; + + if (typeof mapping.lastGeneratedColumn === "number") { + mapping.lastGeneratedColumn += columnShift; + } } - mappings.push({ - line: util.getArg(mapping, "generatedLine", null), - column: util.getArg(mapping, "generatedColumn", null), - lastColumn, - }); - mapping = this._originalMappings[++index]; - } - } else { - const originalColumn = mapping.originalColumn; - - // Iterate until either we run out of mappings, or we run into - // a mapping for a different line than the one we were searching for. - // Since mappings are sorted, this is guaranteed to find all mappings for - // the line we are searching for. - while (mapping && - mapping.originalLine === line && - mapping.originalColumn == originalColumn) { - let lastColumn = mapping.lastGeneratedColumn; - if (this._computedColumnSpans && lastColumn === null) { - lastColumn = Infinity; + if ( + mapping.lastGeneratedColumn === Infinity && + nextSection && + mapping.generatedLine === nextSection.generatedOffset.generatedLine + ) { + mapping.lastGeneratedColumn = + nextSection.generatedOffset.generatedColumn - 2; } - mappings.push({ - line: util.getArg(mapping, "generatedLine", null), - column: util.getArg(mapping, "generatedColumn", null), - lastColumn, - }); + mapping.generatedLine += lineShift; - mapping = this._originalMappings[++index]; - } - } - } + aCallback.call(this, mapping); + }, + aContext, + aOrder + ); + }); + } - return mappings; + computeColumnSpans() { + for (let i = 0; i < this._sections.length; i++) { + this._sections[i].consumer.computeColumnSpans(); + } } destroy() { @@ -1226,7 +1069,8 @@ function _factory(aSourceMap, aSourceMapURL) { sourceMap = util.parseSourceMapInput(aSourceMap); } - const consumer = sourceMap.sections != null + const consumer = + sourceMap.sections != null ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); return Promise.resolve(consumer); diff --git a/lib/source-map-generator.js b/lib/source-map-generator.js index 8111e061..847017fa 100644 --- a/lib/source-map-generator.js +++ b/lib/source-map-generator.js @@ -41,14 +41,14 @@ class SourceMapGenerator { const sourceRoot = aSourceMapConsumer.sourceRoot; const generator = new SourceMapGenerator({ file: aSourceMapConsumer.file, - sourceRoot + sourceRoot, }); - aSourceMapConsumer.eachMapping(function(mapping) { + aSourceMapConsumer.eachMapping(function (mapping) { const newMapping = { generated: { line: mapping.generatedLine, - column: mapping.generatedColumn - } + column: mapping.generatedColumn, + }, }; if (mapping.source != null) { @@ -59,7 +59,7 @@ class SourceMapGenerator { newMapping.original = { line: mapping.originalLine, - column: mapping.originalColumn + column: mapping.originalColumn, }; if (mapping.name != null) { @@ -69,9 +69,9 @@ class SourceMapGenerator { generator.addMapping(newMapping); }); - aSourceMapConsumer.sources.forEach(function(sourceFile) { + aSourceMapConsumer.sources.forEach(function (sourceFile) { let sourceRelative = sourceFile; - if (sourceRoot !== null) { + if (sourceRoot != null) { sourceRelative = util.relative(sourceRoot, sourceFile); } @@ -124,10 +124,10 @@ class SourceMapGenerator { this._mappings.add({ generatedLine: generated.line, generatedColumn: generated.column, - originalLine: original != null && original.line, - originalColumn: original != null && original.column, + originalLine: original && original.line, + originalColumn: original && original.column, source, - name + name, }); } @@ -180,7 +180,7 @@ class SourceMapGenerator { if (aSourceMapConsumer.file == null) { throw new Error( "SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, " + - 'or the source map\'s "file" property. Both were omitted.' + 'or the source map\'s "file" property. Both were omitted.' ); } sourceFile = aSourceMapConsumer.file; @@ -192,18 +192,17 @@ class SourceMapGenerator { } // Applying the SourceMap can add and remove items from the sources and // the names array. - const newSources = this._mappings.toArray().length > 0 - ? new ArraySet() - : this._sources; + const newSources = + this._mappings.toArray().length > 0 ? new ArraySet() : this._sources; const newNames = new ArraySet(); // Find mappings for the "sourceFile" - this._mappings.unsortedForEach(function(mapping) { + this._mappings.unsortedForEach(function (mapping) { if (mapping.source === sourceFile && mapping.originalLine != null) { // Check if it can be mapped by the source map, then update the mapping. const original = aSourceMapConsumer.originalPositionFor({ line: mapping.originalLine, - column: mapping.originalColumn + column: mapping.originalColumn, }); if (original.source != null) { // Copy mapping @@ -231,13 +230,12 @@ class SourceMapGenerator { if (name != null && !newNames.has(name)) { newNames.add(name); } - }, this); this._sources = newSources; this._names = newNames; // Copy sourcesContents of applied map. - aSourceMapConsumer.sources.forEach(function(srcFile) { + aSourceMapConsumer.sources.forEach(function (srcFile) { const content = aSourceMapConsumer.sourceContentFor(srcFile); if (content != null) { if (aSourceMapPath != null) { @@ -267,33 +265,53 @@ class SourceMapGenerator { // it is most likely a programmer error. In this case we throw a very // specific error message to try to guide them the right way. // For example: https://github.com/Polymer/polymer-bundler/pull/519 - if (aOriginal && typeof aOriginal.line !== "number" && typeof aOriginal.column !== "number") { - throw new Error( - "original.line and original.column are not numbers -- you probably meant to omit " + - "the original mapping entirely and only map the generated position. If so, pass " + - "null for the original mapping instead of an object with empty or null values." - ); + if ( + aOriginal && + typeof aOriginal.line !== "number" && + typeof aOriginal.column !== "number" + ) { + throw new Error( + "original.line and original.column are not numbers -- you probably meant to omit " + + "the original mapping entirely and only map the generated position. If so, pass " + + "null for the original mapping instead of an object with empty or null values." + ); } - if (aGenerated && "line" in aGenerated && "column" in aGenerated - && aGenerated.line > 0 && aGenerated.column >= 0 - && !aOriginal && !aSource && !aName) { + if ( + aGenerated && + "line" in aGenerated && + "column" in aGenerated && + aGenerated.line > 0 && + aGenerated.column >= 0 && + !aOriginal && + !aSource && + !aName + ) { // Case 1. - - } else if (aGenerated && "line" in aGenerated && "column" in aGenerated - && aOriginal && "line" in aOriginal && "column" in aOriginal - && aGenerated.line > 0 && aGenerated.column >= 0 - && aOriginal.line > 0 && aOriginal.column >= 0 - && aSource) { + } else if ( + aGenerated && + "line" in aGenerated && + "column" in aGenerated && + aOriginal && + "line" in aOriginal && + "column" in aOriginal && + aGenerated.line > 0 && + aGenerated.column >= 0 && + aOriginal.line > 0 && + aOriginal.column >= 0 && + aSource + ) { // Cases 2 and 3. - } else { - throw new Error("Invalid mapping: " + JSON.stringify({ - generated: aGenerated, - source: aSource, - original: aOriginal, - name: aName - })); + throw new Error( + "Invalid mapping: " + + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName, + }) + ); } } @@ -326,14 +344,17 @@ class SourceMapGenerator { previousGeneratedLine++; } } else if (i > 0) { - if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + if ( + !util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1]) + ) { continue; } next += ","; } - next += base64VLQ.encode(mapping.generatedColumn - - previousGeneratedColumn); + next += base64VLQ.encode( + mapping.generatedColumn - previousGeneratedColumn + ); previousGeneratedColumn = mapping.generatedColumn; if (mapping.source != null) { @@ -342,12 +363,14 @@ class SourceMapGenerator { previousSource = sourceIdx; // lines are stored 0-based in SourceMap spec version 3 - next += base64VLQ.encode(mapping.originalLine - 1 - - previousOriginalLine); + next += base64VLQ.encode( + mapping.originalLine - 1 - previousOriginalLine + ); previousOriginalLine = mapping.originalLine - 1; - next += base64VLQ.encode(mapping.originalColumn - - previousOriginalColumn); + next += base64VLQ.encode( + mapping.originalColumn - previousOriginalColumn + ); previousOriginalColumn = mapping.originalColumn; if (mapping.name != null) { @@ -364,7 +387,7 @@ class SourceMapGenerator { } _generateSourcesContent(aSources, aSourceRoot) { - return aSources.map(function(source) { + return aSources.map(function (source) { if (!this._sourcesContents) { return null; } @@ -386,7 +409,7 @@ class SourceMapGenerator { version: this._version, sources: this._sources.toArray(), names: this._names.toArray(), - mappings: this._serializeMappings() + mappings: this._serializeMappings(), }; if (this._file != null) { map.file = this._file; @@ -395,7 +418,10 @@ class SourceMapGenerator { map.sourceRoot = this._sourceRoot; } if (this._sourcesContents) { - map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + map.sourcesContent = this._generateSourcesContent( + map.sources, + map.sourceRoot + ); } return map; diff --git a/lib/source-node.js b/lib/source-node.js index 8a7a157e..ecee1ae6 100644 --- a/lib/source-node.js +++ b/lib/source-node.js @@ -52,7 +52,11 @@ class SourceNode { * @param aRelativePath Optional. The path that relative sources in the * SourceMapConsumer should be relative to. */ - static fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + static fromStringWithSourceMap( + aGeneratedCode, + aSourceMapConsumer, + aRelativePath + ) { // The SourceNode we want to fill with the generated code // and the SourceMap const node = new SourceNode(); @@ -63,20 +67,22 @@ class SourceNode { // Processed fragments are accessed by calling `shiftNextLine`. const remainingLines = aGeneratedCode.split(REGEX_NEWLINE); let remainingLinesIndex = 0; - const shiftNextLine = function() { + const shiftNextLine = function () { const lineContents = getNextLine(); // The last line of a file might not have a newline. const newLine = getNextLine() || ""; return lineContents + newLine; function getNextLine() { - return remainingLinesIndex < remainingLines.length ? - remainingLines[remainingLinesIndex++] : undefined; + return remainingLinesIndex < remainingLines.length + ? remainingLines[remainingLinesIndex++] + : undefined; } }; // We need to remember the position of "remainingLines" - let lastGeneratedLine = 1, lastGeneratedColumn = 0; + let lastGeneratedLine = 1, + lastGeneratedColumn = 0; // The generate SourceNodes we need a code range. // To extract it current and last mapping is used. @@ -84,7 +90,7 @@ class SourceNode { let lastMapping = null; let nextLine; - aSourceMapConsumer.eachMapping(function(mapping) { + aSourceMapConsumer.eachMapping(function (mapping) { if (lastMapping !== null) { // We add the code from "lastMapping" to "mapping": // First check if there is a new line in between. @@ -99,10 +105,13 @@ class SourceNode { // Associate the code between "lastGeneratedColumn" and // "mapping.generatedColumn" with "lastMapping" nextLine = remainingLines[remainingLinesIndex] || ""; - const code = nextLine.substr(0, mapping.generatedColumn - - lastGeneratedColumn); - remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - - lastGeneratedColumn); + const code = nextLine.substr( + 0, + mapping.generatedColumn - lastGeneratedColumn + ); + remainingLines[remainingLinesIndex] = nextLine.substr( + mapping.generatedColumn - lastGeneratedColumn + ); lastGeneratedColumn = mapping.generatedColumn; addMappingWithCode(lastMapping, code); // No more remaining code, continue @@ -120,7 +129,9 @@ class SourceNode { if (lastGeneratedColumn < mapping.generatedColumn) { nextLine = remainingLines[remainingLinesIndex] || ""; node.add(nextLine.substr(0, mapping.generatedColumn)); - remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr( + mapping.generatedColumn + ); lastGeneratedColumn = mapping.generatedColumn; } lastMapping = mapping; @@ -136,7 +147,7 @@ class SourceNode { } // Copy sourcesContent into SourceNode - aSourceMapConsumer.sources.forEach(function(sourceFile) { + aSourceMapConsumer.sources.forEach(function (sourceFile) { const content = aSourceMapConsumer.sourceContentFor(sourceFile); if (content != null) { if (aRelativePath != null) { @@ -155,11 +166,15 @@ class SourceNode { const source = aRelativePath ? util.join(aRelativePath, mapping.source) : mapping.source; - node.add(new SourceNode(mapping.originalLine, - mapping.originalColumn, - source, - code, - mapping.name)); + node.add( + new SourceNode( + mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name + ) + ); } } } @@ -172,7 +187,7 @@ class SourceNode { */ add(aChunk) { if (Array.isArray(aChunk)) { - aChunk.forEach(function(chunk) { + aChunk.forEach(function (chunk) { this.add(chunk); }, this); } else if (aChunk[isSourceNode] || typeof aChunk === "string") { @@ -181,7 +196,8 @@ class SourceNode { } } else { throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + + aChunk ); } return this; @@ -202,7 +218,8 @@ class SourceNode { this.children.unshift(aChunk); } else { throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + + aChunk ); } return this; @@ -222,10 +239,12 @@ class SourceNode { if (chunk[isSourceNode]) { chunk.walk(aFn); } else if (chunk !== "") { - aFn(chunk, { source: this.source, - line: this.line, - column: this.column, - name: this.name }); + aFn(chunk, { + source: this.source, + line: this.line, + column: this.column, + name: this.name, + }); } } } @@ -264,7 +283,10 @@ class SourceNode { if (lastChild[isSourceNode]) { lastChild.replaceRight(aPattern, aReplacement); } else if (typeof lastChild === "string") { - this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + this.children[this.children.length - 1] = lastChild.replace( + aPattern, + aReplacement + ); } else { this.children.push("".replace(aPattern, aReplacement)); } @@ -307,7 +329,7 @@ class SourceNode { */ toString() { let str = ""; - this.walk(function(chunk) { + this.walk(function (chunk) { str += chunk; }); return str; @@ -321,7 +343,7 @@ class SourceNode { const generated = { code: "", line: 1, - column: 0 + column: 0, }; const map = new SourceMapGenerator(aArgs); let sourceMappingActive = false; @@ -329,26 +351,30 @@ class SourceNode { let lastOriginalLine = null; let lastOriginalColumn = null; let lastOriginalName = null; - this.walk(function(chunk, original) { + this.walk(function (chunk, original) { generated.code += chunk; - if (original.source !== null - && original.line !== null - && original.column !== null) { - if (lastOriginalSource !== original.source - || lastOriginalLine !== original.line - || lastOriginalColumn !== original.column - || lastOriginalName !== original.name) { + if ( + original.source !== null && + original.line !== null && + original.column !== null + ) { + if ( + lastOriginalSource !== original.source || + lastOriginalLine !== original.line || + lastOriginalColumn !== original.column || + lastOriginalName !== original.name + ) { map.addMapping({ source: original.source, original: { line: original.line, - column: original.column + column: original.column, }, generated: { line: generated.line, - column: generated.column + column: generated.column, }, - name: original.name + name: original.name, }); } lastOriginalSource = original.source; @@ -360,8 +386,8 @@ class SourceNode { map.addMapping({ generated: { line: generated.line, - column: generated.column - } + column: generated.column, + }, }); lastOriginalSource = null; sourceMappingActive = false; @@ -379,13 +405,13 @@ class SourceNode { source: original.source, original: { line: original.line, - column: original.column + column: original.column, }, generated: { line: generated.line, - column: generated.column + column: generated.column, }, - name: original.name + name: original.name, }); } } else { @@ -393,7 +419,7 @@ class SourceNode { } } }); - this.walkSourceContents(function(sourceFile, sourceContent) { + this.walkSourceContents(function (sourceFile, sourceContent) { map.setSourceContent(sourceFile, sourceContent); }); diff --git a/lib/url.js b/lib/url.js new file mode 100644 index 00000000..8bb71b6a --- /dev/null +++ b/lib/url.js @@ -0,0 +1,13 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ +"use strict"; + +// Note: This file is overridden in the 'package.json#browser' field to +// substitute lib/url-browser.js instead. + +// Use the URL global for Node 10, and the 'url' module for Node 8. +module.exports = typeof URL === "function" ? URL : require("url").URL; diff --git a/lib/util.js b/lib/util.js index 35bd93d6..20fe8f68 100644 --- a/lib/util.js +++ b/lib/util.js @@ -5,6 +5,8 @@ * http://opensource.org/licenses/BSD-3-Clause */ +const URL = require("./url"); + /** * This is a helper function for getting values from parameter/options * objects. @@ -21,270 +23,14 @@ function getArg(aArgs, aName, aDefaultValue) { } else if (arguments.length === 3) { return aDefaultValue; } - throw new Error('"' + aName + '" is a required argument.'); - + throw new Error('"' + aName + '" is a required argument.'); } exports.getArg = getArg; -const urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; -const dataUrlRegexp = /^data:.+\,.+$/; - -function urlParse(aUrl) { - const match = aUrl.match(urlRegexp); - if (!match) { - return null; - } - return { - scheme: match[1], - auth: match[2], - host: match[3], - port: match[4], - path: match[5] - }; -} -exports.urlParse = urlParse; - -function urlGenerate(aParsedUrl) { - let url = ""; - if (aParsedUrl.scheme) { - url += aParsedUrl.scheme + ":"; - } - url += "//"; - if (aParsedUrl.auth) { - url += aParsedUrl.auth + "@"; - } - if (aParsedUrl.host) { - url += aParsedUrl.host; - } - if (aParsedUrl.port) { - url += ":" + aParsedUrl.port; - } - if (aParsedUrl.path) { - url += aParsedUrl.path; - } - return url; -} -exports.urlGenerate = urlGenerate; - -const MAX_CACHED_INPUTS = 32; - -/** - * Takes some function `f(input) -> result` and returns a memoized version of - * `f`. - * - * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The - * memoization is a dumb-simple, linear least-recently-used cache. - */ -function lruMemoize(f) { - const cache = []; - - return function(input) { - for (let i = 0; i < cache.length; i++) { - if (cache[i].input === input) { - const temp = cache[0]; - cache[0] = cache[i]; - cache[i] = temp; - return cache[0].result; - } - } - - const result = f(input); - - cache.unshift({ - input, - result, - }); - - if (cache.length > MAX_CACHED_INPUTS) { - cache.pop(); - } - - return result; - }; -} - -/** - * Normalizes a path, or the path portion of a URL: - * - * - Replaces consecutive slashes with one slash. - * - Removes unnecessary '.' parts. - * - Removes unnecessary '/..' parts. - * - * Based on code in the Node.js 'path' core module. - * - * @param aPath The path or url to normalize. - */ -const normalize = lruMemoize(function normalize(aPath) { - let path = aPath; - const url = urlParse(aPath); - if (url) { - if (!url.path) { - return aPath; - } - path = url.path; - } - const isAbsolute = exports.isAbsolute(path); - - // Split the path into parts between `/` characters. This is much faster than - // using `.split(/\/+/g)`. - const parts = []; - let start = 0; - let i = 0; - while (true) { - start = i; - i = path.indexOf("/", start); - if (i === -1) { - parts.push(path.slice(start)); - break; - } else { - parts.push(path.slice(start, i)); - while (i < path.length && path[i] === "/") { - i++; - } - } - } - - let up = 0; - for (i = parts.length - 1; i >= 0; i--) { - const part = parts[i]; - if (part === ".") { - parts.splice(i, 1); - } else if (part === "..") { - up++; - } else if (up > 0) { - if (part === "") { - // The first part is blank if the path is absolute. Trying to go - // above the root is a no-op. Therefore we can remove all '..' parts - // directly after the root. - parts.splice(i + 1, up); - up = 0; - } else { - parts.splice(i, 2); - up--; - } - } - } - path = parts.join("/"); - - if (path === "") { - path = isAbsolute ? "/" : "."; - } - - if (url) { - url.path = path; - return urlGenerate(url); - } - return path; -}); -exports.normalize = normalize; - -/** - * Joins two paths/URLs. - * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be joined with the root. - * - * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a - * scheme-relative URL: Then the scheme of aRoot, if any, is prepended - * first. - * - Otherwise aPath is a path. If aRoot is a URL, then its path portion - * is updated with the result and aRoot is returned. Otherwise the result - * is returned. - * - If aPath is absolute, the result is aPath. - * - Otherwise the two paths are joined with a slash. - * - Joining for example 'http://' and 'www.example.com' is also supported. - */ -function join(aRoot, aPath) { - if (aRoot === "") { - aRoot = "."; - } - if (aPath === "") { - aPath = "."; - } - const aPathUrl = urlParse(aPath); - const aRootUrl = urlParse(aRoot); - if (aRootUrl) { - aRoot = aRootUrl.path || "/"; - } - - // `join(foo, '//www.example.org')` - if (aPathUrl && !aPathUrl.scheme) { - if (aRootUrl) { - aPathUrl.scheme = aRootUrl.scheme; - } - return urlGenerate(aPathUrl); - } - - if (aPathUrl || aPath.match(dataUrlRegexp)) { - return aPath; - } - - // `join('http://', 'www.example.com')` - if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { - aRootUrl.host = aPath; - return urlGenerate(aRootUrl); - } - - const joined = aPath.charAt(0) === "/" - ? aPath - : normalize(aRoot.replace(/\/+$/, "") + "/" + aPath); - - if (aRootUrl) { - aRootUrl.path = joined; - return urlGenerate(aRootUrl); - } - return joined; -} -exports.join = join; - -exports.isAbsolute = function(aPath) { - return aPath.charAt(0) === "/" || urlRegexp.test(aPath); -}; - -/** - * Make a path relative to a URL or another path. - * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be made relative to aRoot. - */ -function relative(aRoot, aPath) { - if (aRoot === "") { - aRoot = "."; - } - - aRoot = aRoot.replace(/\/$/, ""); - - // It is possible for the path to be above the root. In this case, simply - // checking whether the root is a prefix of the path won't work. Instead, we - // need to remove components from the root one by one, until either we find - // a prefix that fits, or we run out of components to remove. - let level = 0; - while (aPath.indexOf(aRoot + "/") !== 0) { - const index = aRoot.lastIndexOf("/"); - if (index < 0) { - return aPath; - } - - // If the only part of the root that is left is the scheme (i.e. http://, - // file:///, etc.), one or more slashes (/), or simply nothing at all, we - // have exhausted all components, so the path is not relative to the root. - aRoot = aRoot.slice(0, index); - if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { - return aPath; - } - - ++level; - } - - // Make sure we add a "../" for each component we removed from the root. - return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); -} -exports.relative = relative; - -const supportsNullProto = (function() { +const supportsNullProto = (function () { const obj = Object.create(null); return !("__proto__" in obj); -}()); +})(); function identity(s) { return s; @@ -329,15 +75,17 @@ function isProtoString(s) { } /* eslint-disable no-multi-spaces */ - if (s.charCodeAt(length - 1) !== 95 /* '_' */ || - s.charCodeAt(length - 2) !== 95 /* '_' */ || - s.charCodeAt(length - 3) !== 111 /* 'o' */ || - s.charCodeAt(length - 4) !== 116 /* 't' */ || - s.charCodeAt(length - 5) !== 111 /* 'o' */ || - s.charCodeAt(length - 6) !== 114 /* 'r' */ || - s.charCodeAt(length - 7) !== 112 /* 'p' */ || - s.charCodeAt(length - 8) !== 95 /* '_' */ || - s.charCodeAt(length - 9) !== 95 /* '_' */) { + if ( + s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */ + ) { return false; } /* eslint-enable no-multi-spaces */ @@ -351,61 +99,38 @@ function isProtoString(s) { return true; } -/** - * Comparator between two mappings where the original positions are compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same original source/line/column, but different generated - * line and column the same. Useful when searching for a mapping with a - * stubbed out mapping. - */ -function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { - let cmp = strcmp(mappingA.source, mappingB.source); - if (cmp !== 0) { - return cmp; - } - - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; +function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; } - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0 || onlyCompareOriginal) { - return cmp; + if (aStr1 === null) { + return 1; // aStr2 !== null } - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; + if (aStr2 === null) { + return -1; // aStr1 !== null } - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; + if (aStr1 > aStr2) { + return 1; } - return strcmp(mappingA.name, mappingB.name); + return -1; } -exports.compareByOriginalPositions = compareByOriginalPositions; /** - * Comparator between two mappings with deflated source and name indices where + * Comparator between two mappings with inflated source and name strings where * the generated positions are compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same generated line and column, but different - * source/name/original line and column the same. Useful when searching for a - * mapping with a stubbed out mapping. */ -function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { +function compareByGeneratedPositionsInflated(mappingA, mappingB) { let cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp; } cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0 || onlyCompareGenerated) { + if (cmp !== 0) { return cmp; } @@ -426,121 +151,294 @@ function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGene return strcmp(mappingA.name, mappingB.name); } -exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; +exports.compareByGeneratedPositionsInflated = + compareByGeneratedPositionsInflated; -function strcmp(aStr1, aStr2) { - if (aStr1 === aStr2) { - return 0; - } +/** + * Strip any JSON XSSI avoidance prefix from the string (as documented + * in the source maps specification), and then parse the string as + * JSON. + */ +function parseSourceMapInput(str) { + return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, "")); +} +exports.parseSourceMapInput = parseSourceMapInput; - if (aStr1 === null) { - return 1; // aStr2 !== null - } +// We use 'http' as the base here because we want URLs processed relative +// to the safe base to be treated as "special" URLs during parsing using +// the WHATWG URL parsing. This ensures that backslash normalization +// applies to the path and such. +const PROTOCOL = "http:"; +const PROTOCOL_AND_HOST = `${PROTOCOL}//host`; - if (aStr2 === null) { - return -1; // aStr1 !== null +/** + * Make it easy to create small utilities that tweak a URL's path. + */ +function createSafeHandler(cb) { + return input => { + const type = getURLType(input); + const base = buildSafeBase(input); + const url = new URL(input, base); + + cb(url); + + const result = url.toString(); + + if (type === "absolute") { + return result; + } else if (type === "scheme-relative") { + return result.slice(PROTOCOL.length); + } else if (type === "path-absolute") { + return result.slice(PROTOCOL_AND_HOST.length); + } + + // This assumes that the callback will only change + // the path, search and hash values. + return computeRelativeURL(base, result); + }; +} + +function withBase(url, base) { + return new URL(url, base).toString(); +} + +function buildUniqueSegment(prefix, str) { + let id = 0; + do { + const ident = prefix + id++; + if (str.indexOf(ident) === -1) return ident; + } while (true); +} + +function buildSafeBase(str) { + const maxDotParts = str.split("..").length - 1; + + // If we used a segment that also existed in `str`, then we would be unable + // to compute relative paths. For example, if `segment` were just "a": + // + // const url = "../../a/" + // const base = buildSafeBase(url); // http://host/a/a/ + // const joined = "http://host/a/"; + // const result = relative(base, joined); + // + // Expected: "../../a/"; + // Actual: "a/" + // + const segment = buildUniqueSegment("p", str); + + let base = `${PROTOCOL_AND_HOST}/`; + for (let i = 0; i < maxDotParts; i++) { + base += `${segment}/`; } + return base; +} - if (aStr1 > aStr2) { - return 1; +const ABSOLUTE_SCHEME = /^[A-Za-z0-9\+\-\.]+:/; +function getURLType(url) { + if (url[0] === "/") { + if (url[1] === "/") return "scheme-relative"; + return "path-absolute"; } - return -1; + return ABSOLUTE_SCHEME.test(url) ? "absolute" : "path-relative"; } /** - * Comparator between two mappings with inflated source and name strings where - * the generated positions are compared. + * Given two URLs that are assumed to be on the same + * protocol/host/user/password build a relative URL from the + * path, params, and hash values. + * + * @param rootURL The root URL that the target will be relative to. + * @param targetURL The target that the relative URL points to. + * @return A rootURL-relative, normalized URL value. */ -function compareByGeneratedPositionsInflated(mappingA, mappingB) { - let cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; +function computeRelativeURL(rootURL, targetURL) { + if (typeof rootURL === "string") rootURL = new URL(rootURL); + if (typeof targetURL === "string") targetURL = new URL(targetURL); + + const targetParts = targetURL.pathname.split("/"); + const rootParts = rootURL.pathname.split("/"); + + // If we've got a URL path ending with a "/", we remove it since we'd + // otherwise be relative to the wrong location. + if (rootParts.length > 0 && !rootParts[rootParts.length - 1]) { + rootParts.pop(); } - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; + while ( + targetParts.length > 0 && + rootParts.length > 0 && + targetParts[0] === rootParts[0] + ) { + targetParts.shift(); + rootParts.shift(); } - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp !== 0) { - return cmp; + const relativePath = rootParts + .map(() => "..") + .concat(targetParts) + .join("/"); + + return relativePath + targetURL.search + targetURL.hash; +} + +/** + * Given a URL, ensure that it is treated as a directory URL. + * + * @param url + * @return A normalized URL value. + */ +const ensureDirectory = createSafeHandler(url => { + url.pathname = url.pathname.replace(/\/?$/, "/"); +}); + +/** + * Given a URL, strip off any filename if one is present. + * + * @param url + * @return A normalized URL value. + */ +const trimFilename = createSafeHandler(url => { + url.href = new URL(".", url.toString()).toString(); +}); + +/** + * Normalize a given URL. + * * Convert backslashes. + * * Remove any ".." and "." segments. + * + * @param url + * @return A normalized URL value. + */ +const normalize = createSafeHandler(url => {}); +exports.normalize = normalize; + +/** + * Joins two paths/URLs. + * + * All returned URLs will be normalized. + * + * @param aRoot The root path or URL. Assumed to reference a directory. + * @param aPath The path or URL to be joined with the root. + * @return A joined and normalized URL value. + */ +function join(aRoot, aPath) { + const pathType = getURLType(aPath); + const rootType = getURLType(aRoot); + + aRoot = ensureDirectory(aRoot); + + if (pathType === "absolute") { + return withBase(aPath, undefined); + } + if (rootType === "absolute") { + return withBase(aPath, aRoot); } - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; + if (pathType === "scheme-relative") { + return normalize(aPath); + } + if (rootType === "scheme-relative") { + return withBase(aPath, withBase(aRoot, PROTOCOL_AND_HOST)).slice( + PROTOCOL.length + ); } - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0) { - return cmp; + if (pathType === "path-absolute") { + return normalize(aPath); + } + if (rootType === "path-absolute") { + return withBase(aPath, withBase(aRoot, PROTOCOL_AND_HOST)).slice( + PROTOCOL_AND_HOST.length + ); } - return strcmp(mappingA.name, mappingB.name); + const base = buildSafeBase(aPath + aRoot); + const newPath = withBase(aPath, withBase(aRoot, base)); + return computeRelativeURL(base, newPath); } -exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; +exports.join = join; /** - * Strip any JSON XSSI avoidance prefix from the string (as documented - * in the source maps specification), and then parse the string as - * JSON. + * Make a path relative to a URL or another path. If returning a + * relative URL is not possible, the original target will be returned. + * All returned URLs will be normalized. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + * @return A rootURL-relative (if possible), normalized URL value. */ -function parseSourceMapInput(str) { - return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, "")); +function relative(rootURL, targetURL) { + const result = relativeIfPossible(rootURL, targetURL); + + return typeof result === "string" ? result : normalize(targetURL); +} +exports.relative = relative; + +function relativeIfPossible(rootURL, targetURL) { + const urlType = getURLType(rootURL); + if (urlType !== getURLType(targetURL)) { + return null; + } + + const base = buildSafeBase(rootURL + targetURL); + const root = new URL(rootURL, base); + const target = new URL(targetURL, base); + + try { + new URL("", target.toString()); + } catch (err) { + // Bail if the URL doesn't support things being relative to it, + // For example, data: and blob: URLs. + return null; + } + + if ( + target.protocol !== root.protocol || + target.user !== root.user || + target.password !== root.password || + target.hostname !== root.hostname || + target.port !== root.port + ) { + return null; + } + + return computeRelativeURL(root, target); } -exports.parseSourceMapInput = parseSourceMapInput; /** * Compute the URL of a source given the the source root, the source's * URL, and the source map's URL. */ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { - sourceURL = sourceURL || ""; - - if (sourceRoot) { - // This follows what Chrome does. - if (sourceRoot[sourceRoot.length - 1] !== "/" && sourceURL[0] !== "/") { - sourceRoot += "/"; - } - // The spec says: - // Line 4: An optional source root, useful for relocating source - // files on a server or removing repeated values in the - // “sources” entry. This value is prepended to the individual - // entries in the “source” field. - sourceURL = sourceRoot + sourceURL; - } - - // Historically, SourceMapConsumer did not take the sourceMapURL as - // a parameter. This mode is still somewhat supported, which is why - // this code block is conditional. However, it's preferable to pass - // the source map URL to SourceMapConsumer, so that this function - // can implement the source URL resolution algorithm as outlined in - // the spec. This block is basically the equivalent of: - // new URL(sourceURL, sourceMapURL).toString() - // ... except it avoids using URL, which wasn't available in the - // older releases of node still supported by this library. + // The source map spec states that "sourceRoot" and "sources" entries are to be appended. While + // that is a little vague, implementations have generally interpreted that as joining the + // URLs with a `/` between then, assuming the "sourceRoot" doesn't already end with one. + // For example, // - // The spec says: - // If the sources are not absolute URLs after prepending of the - // “sourceRoot”, the sources are resolved relative to the - // SourceMap (like resolving script src in a html document). - if (sourceMapURL) { - const parsed = urlParse(sourceMapURL); - if (!parsed) { - throw new Error("sourceMapURL could not be parsed"); - } - if (parsed.path) { - // Strip the last path component, but keep the "/". - const index = parsed.path.lastIndexOf("/"); - if (index >= 0) { - parsed.path = parsed.path.substring(0, index + 1); - } - } - sourceURL = join(urlGenerate(parsed), sourceURL); + // sourceRoot: "some-dir", + // sources: ["/some-path.js"] + // + // and + // + // sourceRoot: "some-dir/", + // sources: ["/some-path.js"] + // + // must behave as "some-dir/some-path.js". + // + // With this library's the transition to a more URL-focused implementation, that behavior is + // preserved here. To acheive that, we trim the "/" from absolute-path when a sourceRoot value + // is present in order to make the sources entries behave as if they are relative to the + // "sourceRoot", as they would have if the two strings were simply concated. + if (sourceRoot && getURLType(sourceURL) === "path-absolute") { + sourceURL = sourceURL.replace(/^\//, ""); } - return normalize(sourceURL); + let url = normalize(sourceURL || ""); + + // Parsing URLs can be expensive, so we only perform these joins when needed. + if (sourceRoot) url = join(sourceRoot, url); + if (sourceMapURL) url = join(trimFilename(sourceMapURL), url); + return url; } exports.computeSourceURL = computeSourceURL; diff --git a/lib/wasm.js b/lib/wasm.js index 88b18bea..3091d9ee 100644 --- a/lib/wasm.js +++ b/lib/wasm.js @@ -22,7 +22,8 @@ module.exports = function wasm() { const callbackStack = []; - cachedWasm = readWasm().then(buffer => { + cachedWasm = readWasm() + .then(buffer => { return WebAssembly.instantiate(buffer, { env: { mapping_callback( @@ -64,44 +65,74 @@ module.exports = function wasm() { callbackStack[callbackStack.length - 1](mapping); }, - start_all_generated_locations_for() { console.time("all_generated_locations_for"); }, - end_all_generated_locations_for() { console.timeEnd("all_generated_locations_for"); }, + start_all_generated_locations_for() { + console.time("all_generated_locations_for"); + }, + end_all_generated_locations_for() { + console.timeEnd("all_generated_locations_for"); + }, - start_compute_column_spans() { console.time("compute_column_spans"); }, - end_compute_column_spans() { console.timeEnd("compute_column_spans"); }, + start_compute_column_spans() { + console.time("compute_column_spans"); + }, + end_compute_column_spans() { + console.timeEnd("compute_column_spans"); + }, - start_generated_location_for() { console.time("generated_location_for"); }, - end_generated_location_for() { console.timeEnd("generated_location_for"); }, + start_generated_location_for() { + console.time("generated_location_for"); + }, + end_generated_location_for() { + console.timeEnd("generated_location_for"); + }, - start_original_location_for() { console.time("original_location_for"); }, - end_original_location_for() { console.timeEnd("original_location_for"); }, + start_original_location_for() { + console.time("original_location_for"); + }, + end_original_location_for() { + console.timeEnd("original_location_for"); + }, - start_parse_mappings() { console.time("parse_mappings"); }, - end_parse_mappings() { console.timeEnd("parse_mappings"); }, + start_parse_mappings() { + console.time("parse_mappings"); + }, + end_parse_mappings() { + console.timeEnd("parse_mappings"); + }, - start_sort_by_generated_location() { console.time("sort_by_generated_location"); }, - end_sort_by_generated_location() { console.timeEnd("sort_by_generated_location"); }, + start_sort_by_generated_location() { + console.time("sort_by_generated_location"); + }, + end_sort_by_generated_location() { + console.timeEnd("sort_by_generated_location"); + }, - start_sort_by_original_location() { console.time("sort_by_original_location"); }, - end_sort_by_original_location() { console.timeEnd("sort_by_original_location"); }, - } + start_sort_by_original_location() { + console.time("sort_by_original_location"); + }, + end_sort_by_original_location() { + console.timeEnd("sort_by_original_location"); + }, + }, }); - }).then(Wasm => { - return { - exports: Wasm.instance.exports, - withMappingCallback: (mappingCallback, f) => { - callbackStack.push(mappingCallback); - try { - f(); - } finally { - callbackStack.pop(); - } - } - }; - }).then(null, e => { - cachedWasm = null; - throw e; - }); + }) + .then(Wasm => { + return { + exports: Wasm.instance.exports, + withMappingCallback: (mappingCallback, f) => { + callbackStack.push(mappingCallback); + try { + f(); + } finally { + callbackStack.pop(); + } + }, + }; + }) + .then(null, e => { + cachedWasm = null; + throw e; + }); return cachedWasm; }; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..6dd43d16 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3954 @@ +{ + "name": "source-map", + "version": "0.8.0-beta.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "source-map", + "version": "0.8.0-beta.0", + "license": "BSD-3-Clause", + "devDependencies": { + "c8": "^7.12.0", + "doctoc": "^2.2.1", + "eslint": "^8.24.0", + "eslint-config-prettier": "^8.5.0", + "prettier": "^2.7.1" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@textlint/ast-node-types": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-12.2.2.tgz", + "integrity": "sha512-VQAXUSGdmEajHXrMxeM9ZTS8UBJSVB0ghJFHpFfqYKlcDsjIqClSmTprY6521HoCoSLoUIGBxTC3jQyUMJFIWw==", + "dev": true + }, + "node_modules/@textlint/markdown-to-ast": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-12.2.3.tgz", + "integrity": "sha512-omZqcZV1Q8t9K0IKvlHNIdTV3SKNaS2P5qkbTjzDj7PuTuvG20JFqL9Naiwwi9ty3NzTzq+W8lLG3H2HgX0WvA==", + "dev": true, + "dependencies": { + "@textlint/ast-node-types": "^12.2.2", + "debug": "^4.3.4", + "mdast-util-gfm-autolink-literal": "^0.1.3", + "remark-footnotes": "^3.0.0", + "remark-frontmatter": "^3.0.0", + "remark-gfm": "^1.0.0", + "remark-parse": "^9.0.0", + "traverse": "^0.6.7", + "unified": "^9.2.2" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/anchor-markdown-header": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.6.0.tgz", + "integrity": "sha512-v7HJMtE1X7wTpNFseRhxsY/pivP4uAJbidVhPT+yhz4i/vV1+qx371IXuV9V7bN6KjFtheLJxqaSm0Y/8neJTA==", + "dev": true, + "dependencies": { + "emoji-regex": "~10.1.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctoc": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/doctoc/-/doctoc-2.2.1.tgz", + "integrity": "sha512-qNJ1gsuo7hH40vlXTVVrADm6pdg30bns/Mo7Nv1SxuXSM1bwF9b4xQ40a6EFT/L1cI+Yylbyi8MPI4G4y7XJzQ==", + "dev": true, + "dependencies": { + "@textlint/markdown-to-ast": "^12.1.1", + "anchor-markdown-header": "^0.6.0", + "htmlparser2": "^7.2.0", + "minimist": "^1.2.6", + "underscore": "^1.13.2", + "update-section": "^0.3.3" + }, + "bin": { + "doctoc": "doctoc.js" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", + "dev": true + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", + "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dev": true, + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-footnote": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz", + "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==", + "dev": true, + "dependencies": { + "mdast-util-to-markdown": "^0.6.0", + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", + "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", + "dev": true, + "dependencies": { + "micromark-extension-frontmatter": "^0.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", + "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", + "dev": true, + "dependencies": { + "mdast-util-gfm-autolink-literal": "^0.1.0", + "mdast-util-gfm-strikethrough": "^0.2.0", + "mdast-util-gfm-table": "^0.1.0", + "mdast-util-gfm-task-list-item": "^0.1.0", + "mdast-util-to-markdown": "^0.6.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", + "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dev": true, + "dependencies": { + "ccount": "^1.0.0", + "mdast-util-find-and-replace": "^1.1.0", + "micromark": "^2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dev": true, + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "dev": true, + "dependencies": { + "markdown-table": "^2.0.0", + "mdast-util-to-markdown": "~0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dev": true, + "dependencies": { + "mdast-util-to-markdown": "~0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromark-extension-footnote": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz", + "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==", + "dev": true, + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", + "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", + "dev": true, + "dependencies": { + "fault": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", + "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dev": true, + "dependencies": { + "micromark": "~2.11.0", + "micromark-extension-gfm-autolink-literal": "~0.5.0", + "micromark-extension-gfm-strikethrough": "~0.6.5", + "micromark-extension-gfm-table": "~0.4.0", + "micromark-extension-gfm-tagfilter": "~0.3.0", + "micromark-extension-gfm-task-list-item": "~0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", + "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dev": true, + "dependencies": { + "micromark": "~2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", + "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dev": true, + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", + "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dev": true, + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dev": true, + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/remark-footnotes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz", + "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==", + "dev": true, + "dependencies": { + "mdast-util-footnote": "^0.1.0", + "micromark-extension-footnote": "^0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-frontmatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", + "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", + "dev": true, + "dependencies": { + "mdast-util-frontmatter": "^0.2.0", + "micromark-extension-frontmatter": "^0.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "dev": true, + "dependencies": { + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "dev": true, + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-section": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz", + "integrity": "sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, + "dependencies": { + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@textlint/ast-node-types": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-12.2.2.tgz", + "integrity": "sha512-VQAXUSGdmEajHXrMxeM9ZTS8UBJSVB0ghJFHpFfqYKlcDsjIqClSmTprY6521HoCoSLoUIGBxTC3jQyUMJFIWw==", + "dev": true + }, + "@textlint/markdown-to-ast": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-12.2.3.tgz", + "integrity": "sha512-omZqcZV1Q8t9K0IKvlHNIdTV3SKNaS2P5qkbTjzDj7PuTuvG20JFqL9Naiwwi9ty3NzTzq+W8lLG3H2HgX0WvA==", + "dev": true, + "requires": { + "@textlint/ast-node-types": "^12.2.2", + "debug": "^4.3.4", + "mdast-util-gfm-autolink-literal": "^0.1.3", + "remark-footnotes": "^3.0.0", + "remark-frontmatter": "^3.0.0", + "remark-gfm": "^1.0.0", + "remark-parse": "^9.0.0", + "traverse": "^0.6.7", + "unified": "^9.2.2" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "anchor-markdown-header": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.6.0.tgz", + "integrity": "sha512-v7HJMtE1X7wTpNFseRhxsY/pivP4uAJbidVhPT+yhz4i/vV1+qx371IXuV9V7bN6KjFtheLJxqaSm0Y/8neJTA==", + "dev": true, + "requires": { + "emoji-regex": "~10.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctoc": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/doctoc/-/doctoc-2.2.1.tgz", + "integrity": "sha512-qNJ1gsuo7hH40vlXTVVrADm6pdg30bns/Mo7Nv1SxuXSM1bwF9b4xQ40a6EFT/L1cI+Yylbyi8MPI4G4y7XJzQ==", + "dev": true, + "requires": { + "@textlint/markdown-to-ast": "^12.1.1", + "anchor-markdown-header": "^0.6.0", + "htmlparser2": "^7.2.0", + "minimist": "^1.2.6", + "underscore": "^1.13.2", + "update-section": "^0.3.3" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "emoji-regex": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", + "dev": true + }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", + "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + } + }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dev": true, + "requires": { + "format": "^0.2.0" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "requires": { + "repeat-string": "^1.0.0" + } + }, + "mdast-util-find-and-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dev": true, + "requires": { + "escape-string-regexp": "^4.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "mdast-util-footnote": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz", + "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==", + "dev": true, + "requires": { + "mdast-util-to-markdown": "^0.6.0", + "micromark": "~2.11.0" + } + }, + "mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "mdast-util-frontmatter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", + "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", + "dev": true, + "requires": { + "micromark-extension-frontmatter": "^0.2.0" + } + }, + "mdast-util-gfm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", + "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", + "dev": true, + "requires": { + "mdast-util-gfm-autolink-literal": "^0.1.0", + "mdast-util-gfm-strikethrough": "^0.2.0", + "mdast-util-gfm-table": "^0.1.0", + "mdast-util-gfm-task-list-item": "^0.1.0", + "mdast-util-to-markdown": "^0.6.1" + } + }, + "mdast-util-gfm-autolink-literal": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", + "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "mdast-util-find-and-replace": "^1.1.0", + "micromark": "^2.11.3" + } + }, + "mdast-util-gfm-strikethrough": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dev": true, + "requires": { + "mdast-util-to-markdown": "^0.6.0" + } + }, + "mdast-util-gfm-table": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "dev": true, + "requires": { + "markdown-table": "^2.0.0", + "mdast-util-to-markdown": "~0.6.0" + } + }, + "mdast-util-gfm-task-list-item": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dev": true, + "requires": { + "mdast-util-to-markdown": "~0.6.0" + } + }, + "mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true + }, + "micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "micromark-extension-footnote": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz", + "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==", + "dev": true, + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-frontmatter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", + "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", + "dev": true, + "requires": { + "fault": "^1.0.0" + } + }, + "micromark-extension-gfm": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", + "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dev": true, + "requires": { + "micromark": "~2.11.0", + "micromark-extension-gfm-autolink-literal": "~0.5.0", + "micromark-extension-gfm-strikethrough": "~0.6.5", + "micromark-extension-gfm-table": "~0.4.0", + "micromark-extension-gfm-tagfilter": "~0.3.0", + "micromark-extension-gfm-task-list-item": "~0.3.0" + } + }, + "micromark-extension-gfm-autolink-literal": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", + "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dev": true, + "requires": { + "micromark": "~2.11.3" + } + }, + "micromark-extension-gfm-strikethrough": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", + "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dev": true, + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-gfm-table": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", + "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dev": true, + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-gfm-tagfilter": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", + "dev": true + }, + "micromark-extension-gfm-task-list-item": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dev": true, + "requires": { + "micromark": "~2.11.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "remark-footnotes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz", + "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==", + "dev": true, + "requires": { + "mdast-util-footnote": "^0.1.0", + "micromark-extension-footnote": "^0.3.0" + } + }, + "remark-frontmatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", + "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", + "dev": true, + "requires": { + "mdast-util-frontmatter": "^0.2.0", + "micromark-extension-frontmatter": "^0.2.0" + } + }, + "remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "dev": true, + "requires": { + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" + } + }, + "remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, + "requires": { + "mdast-util-from-markdown": "^0.8.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + } + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "update-section": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz", + "integrity": "sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 6c177549..06d4f1a3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "source-map", "description": "Generates and consumes source maps", - "version": "0.7.3", + "version": "0.7.6", "homepage": "https://github.com/mozilla/source-map", "author": "Nick Fitzgerald ", "contributors": [ @@ -48,44 +48,32 @@ }, "main": "./source-map.js", "types": "./source-map.d.ts", + "browser": { + "./lib/read-wasm.js": "./lib/read-wasm-browser.js" + }, "files": [ "source-map.js", "source-map.d.ts", - "lib/", - "dist/source-map.js" + "lib/" ], "engines": { - "node": ">= 8" + "node": ">= 12" }, "license": "BSD-3-Clause", "scripts": { - "lint": "eslint *.js lib/ test/", - "prebuild": "npm run lint", - "build": "webpack --color", - "pretest": "npm run build", - "test": "node test/run-tests.js", - "precoverage": "npm run build", - "coverage": "nyc node test/run-tests.js", - "setup": "mkdir -p coverage && cp -n .waiting.html coverage/index.html || true", - "dev:live": "live-server --port=4103 --ignorePattern='(js|css|png)$' coverage", - "dev:watch": "watch 'npm run coverage' lib/ test/", - "predev": "npm run setup", - "dev": "npm-run-all -p --silent dev:*", - "clean": "rm -rf coverage .nyc_output", - "toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md" + "lint": "eslint --fix *.js lib/ test/ --ignore-pattern 'test/source-map-tests/**'", + "test": "git submodule update --init --recursive; node test/run-tests.js", + "coverage": "c8 --reporter=text --reporter=html npm test", + "prettier": "prettier --write .", + "clean": "rm -rf coverage", + "toc": "doctoc --github --notitle README.md CONTRIBUTING.md" }, "devDependencies": { - "doctoc": "^1.3.1", - "eslint": "^4.19.1", - "live-server": "^1.2.0", - "npm-run-all": "^4.1.2", - "nyc": "^11.7.1", - "watch": "^1.0.2", - "webpack": "^4.9.1", - "webpack-cli": "^3.1" - }, - "nyc": { - "reporter": "html" + "c8": "^7.12.0", + "doctoc": "^2.2.1", + "eslint": "^8.24.0", + "eslint-config-prettier": "^8.5.0", + "prettier": "^2.7.1" }, - "typings": "source-map" + "dependencies": {} } diff --git a/source-map.d.ts b/source-map.d.ts index 24593915..8bd5b6a1 100644 --- a/source-map.d.ts +++ b/source-map.d.ts @@ -7,363 +7,417 @@ export type SourceMapUrl = string; export interface StartOfSourceMap { - file?: string; - sourceRoot?: string; - skipValidation?: boolean; + file?: string; + sourceRoot?: string; + skipValidation?: boolean; } export interface RawSourceMap { - version: number; - sources: string[]; - names: string[]; - sourceRoot?: string; - sourcesContent?: string[]; - mappings: string; - file: string; + version: number; + sources: string[]; + names: string[]; + sourceRoot?: string; + sourcesContent?: string[]; + mappings: string; + file: string; } export interface RawIndexMap extends StartOfSourceMap { - version: number; - sections: RawSection[]; + version: number; + sections: RawSection[]; } export interface RawSection { - offset: Position; - map: RawSourceMap; + offset: Position; + map: RawSourceMap; } export interface Position { - line: number; - column: number; + line: number; + column: number; } export interface NullablePosition { - line: number | null; - column: number | null; - lastColumn: number | null; + line: number | null; + column: number | null; + lastColumn: number | null; } export interface MappedPosition { - source: string; - line: number; - column: number; - name?: string; + source: string; + line: number; + column: number; + name?: string; } export interface NullableMappedPosition { - source: string | null; - line: number | null; - column: number | null; - name: string | null; + source: string | null; + line: number | null; + column: number | null; + name: string | null; } export interface MappingItem { - source: string; - generatedLine: number; - generatedColumn: number; - originalLine: number; - originalColumn: number; - name: string; + source: string; + generatedLine: number; + generatedColumn: number; + lastGeneratedColumn: number | null; + originalLine: number; + originalColumn: number; + name: string; } export interface Mapping { - generated: Position; - original: Position; - source: string; - name?: string; + generated: Position; + original: Position; + source: string; + name?: string; } export interface CodeWithSourceMap { - code: string; - map: SourceMapGenerator; + code: string; + map: SourceMapGenerator; +} + +export interface SourceMappings { + "lib/mappings.wasm": SourceMapUrl | ArrayBuffer; } export interface SourceMapConsumer { - /** - * Compute the last column for each generated mapping. The last column is - * inclusive. - */ - computeColumnSpans(): void; - - /** - * Returns the original source, line, and column information for the generated - * source's line and column positions provided. The only argument is an object - * with the following properties: - * - * - line: The line number in the generated source. - * - column: The column number in the generated source. - * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or - * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. - * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. - * - * and an object is returned with the following properties: - * - * - source: The original source file, or null. - * - line: The line number in the original source, or null. - * - column: The column number in the original source, or null. - * - name: The original identifier, or null. - */ - originalPositionFor(generatedPosition: Position & { bias?: number }): NullableMappedPosition; - - /** - * Returns the generated line and column information for the original source, - * line, and column positions provided. The only argument is an object with - * the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: The column number in the original source. - * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or - * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. - * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. - * - * and an object is returned with the following properties: - * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. - */ - generatedPositionFor(originalPosition: MappedPosition & { bias?: number }): NullablePosition; - - /** - * Returns all generated line and column information for the original source, - * line, and column provided. If no column is provided, returns all mappings - * corresponding to a either the line we are searching for or the next - * closest line that has any mappings. Otherwise, returns all mappings - * corresponding to the given line and either the column we are searching for - * or the next closest column that has any offsets. - * - * The only argument is an object with the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: Optional. the column number in the original source. - * - * and an array of objects is returned, each with the following properties: - * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. - */ - allGeneratedPositionsFor(originalPosition: MappedPosition): NullablePosition[]; - - /** - * Return true if we have the source content for every source in the source - * map, false otherwise. - */ - hasContentsOfAllSources(): boolean; - - /** - * Returns the original source content. The only argument is the url of the - * original source file. Returns null if no original source content is - * available. - */ - sourceContentFor(source: string, returnNullOnMissing?: boolean): string | null; - - /** - * Iterate over each mapping between an original source/line/column and a - * generated line/column in this source map. - * - * @param callback - * The function that is called with each mapping. - * @param context - * Optional. If specified, this object will be the value of `this` every - * time that `aCallback` is called. - * @param order - * Either `SourceMapConsumer.GENERATED_ORDER` or - * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to - * iterate over the mappings sorted by the generated file's line/column - * order or the original's source/line/column order, respectively. Defaults to - * `SourceMapConsumer.GENERATED_ORDER`. - */ - eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void; - /** - * Free this source map consumer's associated wasm data that is manually-managed. - * Alternatively, you can use SourceMapConsumer.with to avoid needing to remember to call destroy. - */ - destroy(): void; + /** + * When using SourceMapConsumer outside of node.js, for example on the Web, it + * needs to know from what URL to load lib/mappings.wasm. You must inform it + * by calling initialize before constructing any SourceMapConsumers. + * + * @param mappings an object with the following property: + * - "lib/mappings.wasm": A String containing the URL of the + * lib/mappings.wasm file, or an ArrayBuffer with the contents of + * lib/mappings.wasm. + */ + initialize(mappings: SourceMappings): void; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + computeColumnSpans(): void; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + originalPositionFor( + generatedPosition: Position & { bias?: number } + ): NullableMappedPosition; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + generatedPositionFor( + originalPosition: MappedPosition & { bias?: number } + ): NullablePosition; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + allGeneratedPositionsFor( + originalPosition: MappedPosition + ): NullablePosition[]; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + hasContentsOfAllSources(): boolean; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + sourceContentFor( + source: string, + returnNullOnMissing?: boolean + ): string | null; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param callback + * The function that is called with each mapping. + * @param context + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param order + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + eachMapping( + callback: (mapping: MappingItem) => void, + context?: any, + order?: number + ): void; + /** + * Free this source map consumer's associated wasm data that is manually-managed. + * Alternatively, you can use SourceMapConsumer.with to avoid needing to remember to call destroy. + */ + destroy(): void; } export interface SourceMapConsumerConstructor { - prototype: SourceMapConsumer; - - GENERATED_ORDER: number; - ORIGINAL_ORDER: number; - GREATEST_LOWER_BOUND: number; - LEAST_UPPER_BOUND: number; - - new (rawSourceMap: RawSourceMap, sourceMapUrl?: SourceMapUrl): Promise; - new (rawSourceMap: RawIndexMap, sourceMapUrl?: SourceMapUrl): Promise; - new (rawSourceMap: RawSourceMap | RawIndexMap | string, sourceMapUrl?: SourceMapUrl): Promise; - - /** - * Create a BasicSourceMapConsumer from a SourceMapGenerator. - * - * @param sourceMap - * The source map that will be consumed. - */ - fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl?: SourceMapUrl): Promise; - - /** - * Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl` - * (see the `SourceMapConsumer` constructor for details. Then, invoke the `async - * function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait - * for `f` to complete, call `destroy` on the consumer, and return `f`'s return - * value. - * - * You must not use the consumer after `f` completes! - * - * By using `with`, you do not have to remember to manually call `destroy` on - * the consumer, since it will be called automatically once `f` completes. - * - * ```js - * const xSquared = await SourceMapConsumer.with( - * myRawSourceMap, - * null, - * async function (consumer) { - * // Use `consumer` inside here and don't worry about remembering - * // to call `destroy`. - * - * const x = await whatever(consumer); - * return x * x; - * } - * ); - * - * // You may not use that `consumer` anymore out here; it has - * // been destroyed. But you can use `xSquared`. - * console.log(xSquared); - * ``` - */ - with(rawSourceMap: RawSourceMap | RawIndexMap | string, sourceMapUrl: SourceMapUrl | null | undefined, callback: (consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer) => Promise | T): Promise; + prototype: SourceMapConsumer; + + GENERATED_ORDER: number; + ORIGINAL_ORDER: number; + GREATEST_LOWER_BOUND: number; + LEAST_UPPER_BOUND: number; + + new ( + rawSourceMap: RawSourceMap, + sourceMapUrl?: SourceMapUrl + ): Promise; + new ( + rawSourceMap: RawIndexMap, + sourceMapUrl?: SourceMapUrl + ): Promise; + new ( + rawSourceMap: RawSourceMap | RawIndexMap | string, + sourceMapUrl?: SourceMapUrl + ): Promise; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param sourceMap + * The source map that will be consumed. + */ + fromSourceMap( + sourceMap: SourceMapGenerator, + sourceMapUrl?: SourceMapUrl + ): Promise; + + /** + * Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl` + * (see the `SourceMapConsumer` constructor for details. Then, invoke the `async + * function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait + * for `f` to complete, call `destroy` on the consumer, and return `f`'s return + * value. + * + * You must not use the consumer after `f` completes! + * + * By using `with`, you do not have to remember to manually call `destroy` on + * the consumer, since it will be called automatically once `f` completes. + * + * ```js + * const xSquared = await SourceMapConsumer.with( + * myRawSourceMap, + * null, + * async function (consumer) { + * // Use `consumer` inside here and don't worry about remembering + * // to call `destroy`. + * + * const x = await whatever(consumer); + * return x * x; + * } + * ); + * + * // You may not use that `consumer` anymore out here; it has + * // been destroyed. But you can use `xSquared`. + * console.log(xSquared); + * ``` + */ + with( + rawSourceMap: RawSourceMap | RawIndexMap | string, + sourceMapUrl: SourceMapUrl | null | undefined, + callback: ( + consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer + ) => Promise | T + ): Promise; } export const SourceMapConsumer: SourceMapConsumerConstructor; export interface BasicSourceMapConsumer extends SourceMapConsumer { - file: string; - sourceRoot: string; - sources: string[]; - sourcesContent: string[]; + file: string; + sourceRoot: string; + sources: string[]; + sourcesContent: string[]; } export interface BasicSourceMapConsumerConstructor { - prototype: BasicSourceMapConsumer; + prototype: BasicSourceMapConsumer; - new (rawSourceMap: RawSourceMap | string): Promise; + new (rawSourceMap: RawSourceMap | string): Promise; - /** - * Create a BasicSourceMapConsumer from a SourceMapGenerator. - * - * @param sourceMap - * The source map that will be consumed. - */ - fromSourceMap(sourceMap: SourceMapGenerator): Promise; + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param sourceMap + * The source map that will be consumed. + */ + fromSourceMap(sourceMap: SourceMapGenerator): Promise; } export const BasicSourceMapConsumer: BasicSourceMapConsumerConstructor; export interface IndexedSourceMapConsumer extends SourceMapConsumer { - sources: string[]; + sources: string[]; } export interface IndexedSourceMapConsumerConstructor { - prototype: IndexedSourceMapConsumer; + prototype: IndexedSourceMapConsumer; - new (rawSourceMap: RawIndexMap | string): Promise; + new (rawSourceMap: RawIndexMap | string): Promise; } export const IndexedSourceMapConsumer: IndexedSourceMapConsumerConstructor; export class SourceMapGenerator { - constructor(startOfSourceMap?: StartOfSourceMap); - - /** - * Creates a new SourceMapGenerator based on a SourceMapConsumer - * - * @param sourceMapConsumer The SourceMap. - */ - static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator; - - /** - * Add a single mapping from original source line and column to the generated - * source's line and column for this source map being created. The mapping - * object should have the following properties: - * - * - generated: An object with the generated line and column positions. - * - original: An object with the original line and column positions. - * - source: The original source file (relative to the sourceRoot). - * - name: An optional original token name for this mapping. - */ - addMapping(mapping: Mapping): void; - - /** - * Set the source content for a source file. - */ - setSourceContent(sourceFile: string, sourceContent: string): void; - - /** - * Applies the mappings of a sub-source-map for a specific source file to the - * source map being generated. Each mapping to the supplied source file is - * rewritten using the supplied source map. Note: The resolution for the - * resulting mappings is the minimium of this map and the supplied map. - * - * @param sourceMapConsumer The source map to be applied. - * @param sourceFile Optional. The filename of the source file. - * If omitted, SourceMapConsumer's file property will be used. - * @param sourceMapPath Optional. The dirname of the path to the source map - * to be applied. If relative, it is relative to the SourceMapConsumer. - * This parameter is needed when the two source maps aren't in the same - * directory, and the source map to be applied contains relative source - * paths. If so, those relative source paths need to be rewritten - * relative to the SourceMapGenerator. - */ - applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void; - - toString(): string; - - toJSON(): RawSourceMap; + constructor(startOfSourceMap?: StartOfSourceMap); + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param sourceMapConsumer The SourceMap. + */ + static fromSourceMap( + sourceMapConsumer: SourceMapConsumer + ): SourceMapGenerator; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + addMapping(mapping: Mapping): void; + + /** + * Set the source content for a source file. + */ + setSourceContent(sourceFile: string, sourceContent: string): void; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param sourceMapConsumer The source map to be applied. + * @param sourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param sourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + applySourceMap( + sourceMapConsumer: SourceMapConsumer, + sourceFile?: string, + sourceMapPath?: string + ): void; + + toString(): string; + + toJSON(): RawSourceMap; } export class SourceNode { - children: SourceNode[]; - sourceContents: any; - line: number; - column: number; - source: string; - name: string; + children: SourceNode[]; + sourceContents: any; + line: number; + column: number; + source: string; + name: string; - constructor(); - constructor( - line: number | null, - column: number | null, - source: string | null, - chunks?: Array<(string | SourceNode)> | SourceNode | string, - name?: string - ); + constructor(); + constructor( + line: number | null, + column: number | null, + source: string | null, + chunks?: Array | SourceNode | string, + name?: string + ); - static fromStringWithSourceMap( - code: string, - sourceMapConsumer: SourceMapConsumer, - relativePath?: string - ): SourceNode; + static fromStringWithSourceMap( + code: string, + sourceMapConsumer: SourceMapConsumer, + relativePath?: string + ): SourceNode; - add(chunk: Array<(string | SourceNode)> | SourceNode | string): SourceNode; + add(chunk: Array | SourceNode | string): SourceNode; - prepend(chunk: Array<(string | SourceNode)> | SourceNode | string): SourceNode; + prepend(chunk: Array | SourceNode | string): SourceNode; - setSourceContent(sourceFile: string, sourceContent: string): void; + setSourceContent(sourceFile: string, sourceContent: string): void; - walk(fn: (chunk: string, mapping: MappedPosition) => void): void; + walk(fn: (chunk: string, mapping: MappedPosition) => void): void; - walkSourceContents(fn: (file: string, content: string) => void): void; + walkSourceContents(fn: (file: string, content: string) => void): void; - join(sep: string): SourceNode; + join(sep: string): SourceNode; - replaceRight(pattern: string, replacement: string): SourceNode; + replaceRight(pattern: string, replacement: string): SourceNode; - toString(): string; + toString(): string; - toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; + toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; } diff --git a/source-map.js b/source-map.js index a84abf1e..6c73fc02 100644 --- a/source-map.js +++ b/source-map.js @@ -1,8 +1,10 @@ /* * Copyright 2009-2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE.txt or: + * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = require("./lib/source-map-generator").SourceMapGenerator; -exports.SourceMapConsumer = require("./lib/source-map-consumer").SourceMapConsumer; +exports.SourceMapGenerator = + require("./lib/source-map-generator").SourceMapGenerator; +exports.SourceMapConsumer = + require("./lib/source-map-consumer").SourceMapConsumer; exports.SourceNode = require("./lib/source-node").SourceNode; diff --git a/test/run-tests.js b/test/run-tests.js index c43d34dd..667bac3f 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -37,25 +37,26 @@ async function run(tests) { function isTestFile(f) { const testToRun = process.argv[2]; - return testToRun - ? path.basename(testToRun) === f - : /^test\-.*?\.js/.test(f); + return testToRun ? path.basename(testToRun) === f : /^test\-.*?\.js/.test(f); } function toRelativeModule(f) { return "./" + f.replace(/\.js$/, ""); } -const requires = fs.readdirSync(__dirname) +const requires = fs + .readdirSync(__dirname) .filter(isTestFile) .map(toRelativeModule); -run(requires.map(require).map(function(mod, i) { - return { - name: requires[i], - testCase: mod - }; -})).then( +run( + requires.map(require).map(function (mod, i) { + return { + name: requires[i], + testCase: mod, + }; + }) +).then( code => process.exit(code), e => { console.error(e); diff --git a/test/source-map-tests b/test/source-map-tests new file mode 160000 index 00000000..14c89744 --- /dev/null +++ b/test/source-map-tests @@ -0,0 +1 @@ +Subproject commit 14c897444208365fc586a9c00c623bfb1955d731 diff --git a/test/test-api.js b/test/test-api.js index a4068ca9..c6467267 100644 --- a/test/test-api.js +++ b/test/test-api.js @@ -7,7 +7,9 @@ const sourceMap = require("../source-map"); -exports["test that the api is properly exposed in the top level"] = function(assert) { +exports["test that the api is properly exposed in the top level"] = function ( + assert +) { assert.equal(typeof sourceMap.SourceMapGenerator, "function"); assert.equal(typeof sourceMap.SourceMapConsumer, "function"); assert.equal(typeof sourceMap.SourceNode, "function"); diff --git a/test/test-array-set.js b/test/test-array-set.js index ef59fff2..c888e9ed 100644 --- a/test/test-array-set.js +++ b/test/test-array-set.js @@ -15,29 +15,35 @@ function makeTestSet() { return set; } -exports["test .has() membership"] = function(assert) { +exports["test .has() membership"] = function (assert) { const set = makeTestSet(); for (let i = 0; i < 100; i++) { assert.ok(set.has(String(i))); } }; -exports["test .indexOf() elements"] = function(assert) { +exports["test .indexOf() elements"] = function (assert) { const set = makeTestSet(); for (let i = 0; i < 100; i++) { assert.strictEqual(set.indexOf(String(i)), i); } }; -exports["test .at() indexing"] = function(assert) { +exports["test .at() indexing"] = function (assert) { const set = makeTestSet(); for (let i = 0; i < 100; i++) { assert.strictEqual(set.at(i), String(i)); } }; -exports["test creating from an array"] = function(assert) { - const set = ArraySet.fromArray(["foo", "bar", "baz", "quux", "hasOwnProperty"]); +exports["test creating from an array"] = function (assert) { + const set = ArraySet.fromArray([ + "foo", + "bar", + "baz", + "quux", + "hasOwnProperty", + ]); assert.ok(set.has("foo")); assert.ok(set.has("bar")); @@ -56,7 +62,9 @@ exports["test creating from an array"] = function(assert) { assert.strictEqual(set.at(3), "quux"); }; -exports["test that you can add __proto__; see github issue #30"] = function(assert) { +exports["test that you can add __proto__; see github issue #30"] = function ( + assert +) { const set = new ArraySet(); set.add("__proto__"); assert.ok(set.has("__proto__")); @@ -64,7 +72,7 @@ exports["test that you can add __proto__; see github issue #30"] = function(asse assert.strictEqual(set.indexOf("__proto__"), 0); }; -exports["test .fromArray() with duplicates"] = function(assert) { +exports["test .fromArray() with duplicates"] = function (assert) { let set = ArraySet.fromArray(["foo", "foo"]); assert.ok(set.has("foo")); assert.strictEqual(set.at(0), "foo"); @@ -79,7 +87,7 @@ exports["test .fromArray() with duplicates"] = function(assert) { assert.strictEqual(set.toArray().length, 2); }; -exports["test .add() with duplicates"] = function(assert) { +exports["test .add() with duplicates"] = function (assert) { const set = new ArraySet(); set.add("foo"); @@ -97,7 +105,7 @@ exports["test .add() with duplicates"] = function(assert) { assert.strictEqual(set.toArray().length, 2); }; -exports["test .size()"] = function(assert) { +exports["test .size()"] = function (assert) { const set = new ArraySet(); set.add("foo"); set.add("bar"); @@ -105,7 +113,7 @@ exports["test .size()"] = function(assert) { assert.strictEqual(set.size(), 3); }; -exports["test .size() with disallowed duplicates"] = function(assert) { +exports["test .size() with disallowed duplicates"] = function (assert) { const set = new ArraySet(); set.add("foo"); @@ -120,7 +128,7 @@ exports["test .size() with disallowed duplicates"] = function(assert) { assert.strictEqual(set.size(), 3); }; -exports["test .size() with allowed duplicates"] = function(assert) { +exports["test .size() with allowed duplicates"] = function (assert) { const set = new ArraySet(); set.add("foo"); diff --git a/test/test-base64-vlq.js b/test/test-base64-vlq.js index 1d79cef5..a240f5bd 100644 --- a/test/test-base64-vlq.js +++ b/test/test-base64-vlq.js @@ -517,7 +517,7 @@ const vlqs = [ { number: 255, encoded: "+P" }, ]; -exports["test normal encoding and decoding"] = function(assert) { +exports["test normal encoding and decoding"] = function (assert) { for (let i = 0; i < vlqs.length; i++) { const str = base64VLQ.encode(vlqs[i].number); assert.equal( diff --git a/test/test-base64.js b/test/test-base64.js index 787aeb4e..f1e98af0 100644 --- a/test/test-base64.js +++ b/test/test-base64.js @@ -7,16 +7,16 @@ const base64 = require("../lib/base64"); -exports["test out of range encoding"] = function(assert) { - assert.throws(function() { +exports["test out of range encoding"] = function (assert) { + assert.throws(function () { base64.encode(-1); }, /Must be between 0 and 63/); - assert.throws(function() { + assert.throws(function () { base64.encode(64); }, /Must be between 0 and 63/); }; -exports["test normal encoding and decoding"] = function(assert) { +exports["test normal encoding and decoding"] = function (assert) { for (let i = 0; i < 64; i++) { base64.encode(i); } diff --git a/test/test-binary-search.js b/test/test-binary-search.js index 5a31aea7..2d9b2864 100644 --- a/test/test-binary-search.js +++ b/test/test-binary-search.js @@ -11,86 +11,134 @@ function numberCompare(a, b) { return a - b; } -exports["test too high with default (glb) bias"] = function(assert) { +exports["test too high with default (glb) bias"] = function (assert) { const needle = 30; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { binarySearch.search(needle, haystack, numberCompare); }); - assert.equal(haystack[binarySearch.search(needle, haystack, numberCompare)], 20); + assert.equal( + haystack[binarySearch.search(needle, haystack, numberCompare)], + 20 + ); }; -exports["test too low with default (glb) bias"] = function(assert) { +exports["test too low with default (glb) bias"] = function (assert) { const needle = 1; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { binarySearch.search(needle, haystack, numberCompare); }); assert.equal(binarySearch.search(needle, haystack, numberCompare), -1); }; -exports["test too high with lub bias"] = function(assert) { +exports["test too high with lub bias"] = function (assert) { const needle = 30; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { binarySearch.search(needle, haystack, numberCompare); }); - assert.equal(binarySearch.search(needle, haystack, numberCompare, - binarySearch.LEAST_UPPER_BOUND), -1); + assert.equal( + binarySearch.search( + needle, + haystack, + numberCompare, + binarySearch.LEAST_UPPER_BOUND + ), + -1 + ); }; -exports["test too low with lub bias"] = function(assert) { +exports["test too low with lub bias"] = function (assert) { const needle = 1; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { binarySearch.search(needle, haystack, numberCompare); }); - assert.equal(haystack[binarySearch.search(needle, haystack, numberCompare, - binarySearch.LEAST_UPPER_BOUND)], 2); + assert.equal( + haystack[ + binarySearch.search( + needle, + haystack, + numberCompare, + binarySearch.LEAST_UPPER_BOUND + ) + ], + 2 + ); }; -exports["test exact search"] = function(assert) { +exports["test exact search"] = function (assert) { const needle = 4; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.equal(haystack[binarySearch.search(needle, haystack, numberCompare)], 4); + assert.equal( + haystack[binarySearch.search(needle, haystack, numberCompare)], + 4 + ); }; -exports["test fuzzy search with default (glb) bias"] = function(assert) { +exports["test fuzzy search with default (glb) bias"] = function (assert) { const needle = 19; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.equal(haystack[binarySearch.search(needle, haystack, numberCompare)], 18); + assert.equal( + haystack[binarySearch.search(needle, haystack, numberCompare)], + 18 + ); }; -exports["test fuzzy search with lub bias"] = function(assert) { +exports["test fuzzy search with lub bias"] = function (assert) { const needle = 19; const haystack = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - assert.equal(haystack[binarySearch.search(needle, haystack, numberCompare, - binarySearch.LEAST_UPPER_BOUND)], 20); + assert.equal( + haystack[ + binarySearch.search( + needle, + haystack, + numberCompare, + binarySearch.LEAST_UPPER_BOUND + ) + ], + 20 + ); }; -exports["test multiple matches"] = function(assert) { +exports["test multiple matches"] = function (assert) { const needle = 5; const haystack = [1, 1, 2, 5, 5, 5, 13, 21]; - assert.equal(binarySearch.search(needle, haystack, numberCompare, - binarySearch.LEAST_UPPER_BOUND), 3); + assert.equal( + binarySearch.search( + needle, + haystack, + numberCompare, + binarySearch.LEAST_UPPER_BOUND + ), + 3 + ); }; -exports["test multiple matches at the beginning"] = function(assert) { +exports["test multiple matches at the beginning"] = function (assert) { const needle = 1; const haystack = [1, 1, 2, 5, 5, 5, 13, 21]; - assert.equal(binarySearch.search(needle, haystack, numberCompare, - binarySearch.LEAST_UPPER_BOUND), 0); + assert.equal( + binarySearch.search( + needle, + haystack, + numberCompare, + binarySearch.LEAST_UPPER_BOUND + ), + 0 + ); }; diff --git a/test/test-dog-fooding.js b/test/test-dog-fooding.js index 1186785b..42504ca5 100644 --- a/test/test-dog-fooding.js +++ b/test/test-dog-fooding.js @@ -6,97 +6,469 @@ */ const util = require("./util"); -const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; -const SourceMapGenerator = require("../lib/source-map-generator").SourceMapGenerator; +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; +const SourceMapGenerator = + require("../lib/source-map-generator").SourceMapGenerator; -exports["test eating our own dog food"] = async function(assert) { +exports["test eating our own dog food"] = async function (assert) { const smg = new SourceMapGenerator({ file: "testing.js", - sourceRoot: "/wu/tang" + sourceRoot: "/wu/tang", }); smg.addMapping({ source: "gza.coffee", original: { line: 1, column: 0 }, - generated: { line: 2, column: 2 } + generated: { line: 2, column: 2 }, }); smg.addMapping({ source: "gza.coffee", original: { line: 2, column: 0 }, - generated: { line: 3, column: 2 } + generated: { line: 3, column: 2 }, }); smg.addMapping({ source: "gza.coffee", original: { line: 3, column: 0 }, - generated: { line: 4, column: 2 } + generated: { line: 4, column: 2 }, }); smg.addMapping({ source: "gza.coffee", original: { line: 4, column: 0 }, - generated: { line: 5, column: 2 } + generated: { line: 5, column: 2 }, }); smg.addMapping({ source: "gza.coffee", original: { line: 5, column: 10 }, - generated: { line: 6, column: 12 } + generated: { line: 6, column: 12 }, }); const smc = await new SourceMapConsumer(smg.toString()); // Exact - util.assertMapping(2, 2, "/wu/tang/gza.coffee", 1, 0, null, null, smc, assert); - util.assertMapping(3, 2, "/wu/tang/gza.coffee", 2, 0, null, null, smc, assert); - util.assertMapping(4, 2, "/wu/tang/gza.coffee", 3, 0, null, null, smc, assert); - util.assertMapping(5, 2, "/wu/tang/gza.coffee", 4, 0, null, null, smc, assert); - util.assertMapping(6, 12, "/wu/tang/gza.coffee", 5, 10, null, null, smc, assert); + util.assertMapping( + 2, + 2, + "/wu/tang/gza.coffee", + 1, + 0, + null, + null, + smc, + assert + ); + util.assertMapping( + 3, + 2, + "/wu/tang/gza.coffee", + 2, + 0, + null, + null, + smc, + assert + ); + util.assertMapping( + 4, + 2, + "/wu/tang/gza.coffee", + 3, + 0, + null, + null, + smc, + assert + ); + util.assertMapping( + 5, + 2, + "/wu/tang/gza.coffee", + 4, + 0, + null, + null, + smc, + assert + ); + util.assertMapping( + 6, + 12, + "/wu/tang/gza.coffee", + 5, + 10, + null, + null, + smc, + assert + ); // Fuzzy // Generated to original with default (glb) bias. util.assertMapping(2, 0, null, null, null, null, null, smc, assert, true); - util.assertMapping(2, 9, "/wu/tang/gza.coffee", 1, 0, null, null, smc, assert, true); + util.assertMapping( + 2, + 9, + "/wu/tang/gza.coffee", + 1, + 0, + null, + null, + smc, + assert, + true + ); util.assertMapping(3, 0, null, null, null, null, null, smc, assert, true); - util.assertMapping(3, 9, "/wu/tang/gza.coffee", 2, 0, null, null, smc, assert, true); + util.assertMapping( + 3, + 9, + "/wu/tang/gza.coffee", + 2, + 0, + null, + null, + smc, + assert, + true + ); util.assertMapping(4, 0, null, null, null, null, null, smc, assert, true); - util.assertMapping(4, 9, "/wu/tang/gza.coffee", 3, 0, null, null, smc, assert, true); + util.assertMapping( + 4, + 9, + "/wu/tang/gza.coffee", + 3, + 0, + null, + null, + smc, + assert, + true + ); util.assertMapping(5, 0, null, null, null, null, null, smc, assert, true); - util.assertMapping(5, 9, "/wu/tang/gza.coffee", 4, 0, null, null, smc, assert, true); + util.assertMapping( + 5, + 9, + "/wu/tang/gza.coffee", + 4, + 0, + null, + null, + smc, + assert, + true + ); util.assertMapping(6, 0, null, null, null, null, null, smc, assert, true); util.assertMapping(6, 9, null, null, null, null, null, smc, assert, true); - util.assertMapping(6, 13, "/wu/tang/gza.coffee", 5, 10, null, null, smc, assert, true); + util.assertMapping( + 6, + 13, + "/wu/tang/gza.coffee", + 5, + 10, + null, + null, + smc, + assert, + true + ); // Generated to original with lub bias. - util.assertMapping(2, 0, "/wu/tang/gza.coffee", 1, 0, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(2, 9, null, null, null, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(3, 0, "/wu/tang/gza.coffee", 2, 0, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(3, 9, null, null, null, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(4, 0, "/wu/tang/gza.coffee", 3, 0, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(4, 9, null, null, null, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(5, 0, "/wu/tang/gza.coffee", 4, 0, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(5, 9, null, null, null, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(6, 0, "/wu/tang/gza.coffee", 5, 10, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(6, 9, "/wu/tang/gza.coffee", 5, 10, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); - util.assertMapping(6, 13, null, null, null, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, true); + util.assertMapping( + 2, + 0, + "/wu/tang/gza.coffee", + 1, + 0, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 2, + 9, + null, + null, + null, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 3, + 0, + "/wu/tang/gza.coffee", + 2, + 0, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 3, + 9, + null, + null, + null, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 4, + 0, + "/wu/tang/gza.coffee", + 3, + 0, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 4, + 9, + null, + null, + null, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 5, + 0, + "/wu/tang/gza.coffee", + 4, + 0, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 5, + 9, + null, + null, + null, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 6, + 0, + "/wu/tang/gza.coffee", + 5, + 10, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 6, + 9, + "/wu/tang/gza.coffee", + 5, + 10, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); + util.assertMapping( + 6, + 13, + null, + null, + null, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + true + ); // Original to generated with default (glb) bias - util.assertMapping(2, 2, "/wu/tang/gza.coffee", 1, 1, null, null, smc, assert, null, true); - util.assertMapping(3, 2, "/wu/tang/gza.coffee", 2, 3, null, null, smc, assert, null, true); - util.assertMapping(4, 2, "/wu/tang/gza.coffee", 3, 6, null, null, smc, assert, null, true); - util.assertMapping(5, 2, "/wu/tang/gza.coffee", 4, 9, null, null, smc, assert, null, true); - util.assertMapping(5, 2, "/wu/tang/gza.coffee", 5, 9, null, null, smc, assert, null, true); - util.assertMapping(6, 12, "/wu/tang/gza.coffee", 6, 19, null, null, smc, assert, null, true); + util.assertMapping( + 2, + 2, + "/wu/tang/gza.coffee", + 1, + 1, + null, + null, + smc, + assert, + null, + true + ); + util.assertMapping( + 3, + 2, + "/wu/tang/gza.coffee", + 2, + 3, + null, + null, + smc, + assert, + null, + true + ); + util.assertMapping( + 4, + 2, + "/wu/tang/gza.coffee", + 3, + 6, + null, + null, + smc, + assert, + null, + true + ); + util.assertMapping( + 5, + 2, + "/wu/tang/gza.coffee", + 4, + 9, + null, + null, + smc, + assert, + null, + true + ); + util.assertMapping( + 5, + 2, + "/wu/tang/gza.coffee", + 5, + 9, + null, + null, + smc, + assert, + null, + true + ); + util.assertMapping( + 6, + 12, + "/wu/tang/gza.coffee", + 6, + 19, + null, + null, + smc, + assert, + null, + true + ); // Original to generated with lub bias. - util.assertMapping(3, 2, "/wu/tang/gza.coffee", 1, 1, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); - util.assertMapping(4, 2, "/wu/tang/gza.coffee", 2, 3, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); - util.assertMapping(5, 2, "/wu/tang/gza.coffee", 3, 6, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); - util.assertMapping(6, 12, "/wu/tang/gza.coffee", 4, 9, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); - util.assertMapping(6, 12, "/wu/tang/gza.coffee", 5, 9, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); - util.assertMapping(null, null, "/wu/tang/gza.coffee", 6, 19, null, SourceMapConsumer.LEAST_UPPER_BOUND, smc, assert, null, true); + util.assertMapping( + 3, + 2, + "/wu/tang/gza.coffee", + 1, + 1, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); + util.assertMapping( + 4, + 2, + "/wu/tang/gza.coffee", + 2, + 3, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); + util.assertMapping( + 5, + 2, + "/wu/tang/gza.coffee", + 3, + 6, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); + util.assertMapping( + 6, + 12, + "/wu/tang/gza.coffee", + 4, + 9, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); + util.assertMapping( + 6, + 12, + "/wu/tang/gza.coffee", + 5, + 9, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); + util.assertMapping( + null, + null, + "/wu/tang/gza.coffee", + 6, + 19, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + smc, + assert, + null, + true + ); smc.destroy(); }; diff --git a/test/test-nested-consumer-usage.js b/test/test-nested-consumer-usage.js index f8477a61..b0f5c59a 100644 --- a/test/test-nested-consumer-usage.js +++ b/test/test-nested-consumer-usage.js @@ -1,4 +1,4 @@ -const {SourceMapConsumer, SourceMapGenerator} = require("../"); +const { SourceMapConsumer, SourceMapGenerator } = require("../"); const TS_MAP = { version: 3, @@ -9,8 +9,9 @@ const TS_MAP = { mappings: ";;AAKA;IACE,MAAM,CAAC,EAAC,MAAM,EAAE,SAAS,EAAC,CAAC;AAC7B,CAAC;AAFD,yBAEC", sourcesContent: [ - "\ntype Cheese = {\n readonly cheese: string\n}\n\nexport default function Cheese(): Cheese {\n return {cheese: 'stilton'};\n}\n" - ] + "\ntype Cheese = {\n readonly cheese: string\n}\n\nexport default function Cheese(): Cheese {\n" + + " return {cheese: 'stilton'};\n}\n", + ], }; const BABEL_MAP = { @@ -23,21 +24,18 @@ const BABEL_MAP = { "value", "Cheese", "cheese", - "default" + "default", ], mappings: + // eslint-disable-next-line "AAAA;;AACAA,OAAOC,cAAP,CAAsBC,OAAtB,EAA+B,YAA/B,EAA6C,EAAEC,OAAO,IAAT,EAA7C;AACA,SAASC,MAAT,GAAkB;AACd,WAAO,EAAEC,QAAQ,SAAV,EAAP;AACH;AACDH,QAAQI,OAAR,GAAkBF,MAAlB", sourcesContent: [ - '"use strict";\nObject.defineProperty(exports, "__esModule", { value: true });\nfunction Cheese() {\n return { cheese: \'stilton\' };\n}\nexports.default = Cheese;\n//# sourceMappingURL=blah.js.map' - ] + '"use strict";\nObject.defineProperty(exports, "__esModule", { value: true });\nfunction Cheese() {\n' + + " return { cheese: 'stilton' };\n}\nexports.default = Cheese;\n//# sourceMappingURL=blah.js.map", + ], }; - -async function composeSourceMaps( - tsMap, - babelMap, - tsFileName, -) { +async function composeSourceMaps(tsMap, babelMap, tsFileName) { const tsConsumer = await new SourceMapConsumer(tsMap); const babelConsumer = await new SourceMapConsumer(babelMap); const map = new SourceMapGenerator(); @@ -75,6 +73,6 @@ async function composeSourceMaps( return map.toJSON(); } -exports["test nested consumer usage"] = async function(assert) { +exports["test nested consumer usage"] = async function (assert) { await composeSourceMaps(TS_MAP, BABEL_MAP, "blah.tsx"); }; diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js index 6d6d47d4..dc40ba28 100644 --- a/test/test-source-map-consumer.js +++ b/test/test-source-map-consumer.js @@ -6,138 +6,190 @@ */ const util = require("./util"); -const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; -const IndexedSourceMapConsumer = require("../lib/source-map-consumer").IndexedSourceMapConsumer; -const BasicSourceMapConsumer = require("../lib/source-map-consumer").BasicSourceMapConsumer; -const SourceMapGenerator = require("../lib/source-map-generator").SourceMapGenerator; - -exports["test that we can instantiate with a string or an object"] = async function(assert) { - let map = await new SourceMapConsumer(util.testMap); - map = await new SourceMapConsumer(JSON.stringify(util.testMap)); - assert.ok(true); - map.destroy(); -}; +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; +const IndexedSourceMapConsumer = + require("../lib/source-map-consumer").IndexedSourceMapConsumer; +const BasicSourceMapConsumer = + require("../lib/source-map-consumer").BasicSourceMapConsumer; +const SourceMapGenerator = + require("../lib/source-map-generator").SourceMapGenerator; + +exports["test that we can instantiate with a string or an object"] = + async function (assert) { + let map = await new SourceMapConsumer(util.testMap); + map = await new SourceMapConsumer(JSON.stringify(util.testMap)); + assert.ok(true); + map.destroy(); + }; -exports["test that the object returned from await new SourceMapConsumer inherits from SourceMapConsumer"] = async function(assert) { +exports[ + "test that the object returned from await new SourceMapConsumer inherits from SourceMapConsumer" +] = async function (assert) { const map = await new SourceMapConsumer(util.testMap); assert.ok(map instanceof SourceMapConsumer); map.destroy(); }; -exports["test that a BasicSourceMapConsumer is returned for sourcemaps without sections"] = async function(assert) { +exports[ + "test that a BasicSourceMapConsumer is returned for sourcemaps without sections" +] = async function (assert) { const map = await new SourceMapConsumer(util.testMap); assert.ok(map instanceof BasicSourceMapConsumer); map.destroy(); }; -exports["test that an IndexedSourceMapConsumer is returned for sourcemaps with sections"] = async function(assert) { +exports[ + "test that an IndexedSourceMapConsumer is returned for sourcemaps with sections" +] = async function (assert) { const map = await new SourceMapConsumer(util.indexedTestMap); assert.ok(map instanceof IndexedSourceMapConsumer); map.destroy(); }; -exports["test that the `sources` field has the original sources"] = async function(assert) { - let map; - let sources; - - map = await new SourceMapConsumer(util.testMap); - sources = map.sources; - assert.equal(sources[0], "/the/root/one.js"); - assert.equal(sources[1], "/the/root/two.js"); - assert.equal(sources.length, 2); - map.destroy(); - - map = await new SourceMapConsumer(util.indexedTestMap); - sources = map.sources; - assert.equal(sources[0], "/the/root/one.js"); - assert.equal(sources[1], "/the/root/two.js"); - assert.equal(sources.length, 2); - map.destroy(); - - map = await new SourceMapConsumer(util.indexedTestMapDifferentSourceRoots); - sources = map.sources; - assert.equal(sources[0], "/the/root/one.js"); - assert.equal(sources[1], "/different/root/two.js"); - assert.equal(sources.length, 2); - map.destroy(); - - map = await new SourceMapConsumer(util.testMapNoSourceRoot); - sources = map.sources; - assert.equal(sources[0], "one.js"); - assert.equal(sources[1], "two.js"); - assert.equal(sources.length, 2); - map.destroy(); - - map = await new SourceMapConsumer(util.testMapEmptySourceRoot); - sources = map.sources; - assert.equal(sources[0], "one.js"); - assert.equal(sources[1], "two.js"); - assert.equal(sources.length, 2); - map.destroy(); -}; - -exports["test that the source root is reflected in a mapping's source field"] = async function(assert) { - let map; - let mapping; +exports["test that the `sources` field has the original sources"] = + async function (assert) { + let map; + let sources; + + map = await new SourceMapConsumer(util.testMap); + sources = map.sources; + assert.equal(sources[0], "/the/root/one.js"); + assert.equal(sources[1], "/the/root/two.js"); + assert.equal(sources.length, 2); + map.destroy(); + + map = await new SourceMapConsumer(util.indexedTestMap); + sources = map.sources; + assert.equal(sources[0], "/the/root/one.js"); + assert.equal(sources[1], "/the/root/two.js"); + assert.equal(sources.length, 2); + map.destroy(); + + map = await new SourceMapConsumer(util.indexedTestMapDifferentSourceRoots); + sources = map.sources; + assert.equal(sources[0], "/the/root/one.js"); + assert.equal(sources[1], "/different/root/two.js"); + assert.equal(sources.length, 2); + map.destroy(); + + map = await new SourceMapConsumer(util.testMapNoSourceRoot); + sources = map.sources; + assert.equal(sources[0], "one.js"); + assert.equal(sources[1], "two.js"); + assert.equal(sources.length, 2); + map.destroy(); + + map = await new SourceMapConsumer(util.testMapEmptySourceRoot); + sources = map.sources; + assert.equal(sources[0], "one.js"); + assert.equal(sources[1], "two.js"); + assert.equal(sources.length, 2); + map.destroy(); + }; - map = await new SourceMapConsumer(util.testMap); +exports["test that the SourceMapConsumer supports the ignoreList"] = + async function (assert) { + const map = await new SourceMapConsumer(util.testMapWithIgnoreList); + const sources = map.sources; + const ignoreList = map.x_google_ignoreList; + assert.equal(ignoreList.length, 1); + assert.equal(ignoreList[0], 0); + assert.equal(sources[ignoreList[0]], "/the/root/one.js"); + map.destroy(); + }; - mapping = map.originalPositionFor({ - line: 2, - column: 1 - }); - assert.equal(mapping.source, "/the/root/two.js"); +exports["test that the source root is reflected in a mapping's source field"] = + async function (assert) { + let map; + let mapping; - mapping = map.originalPositionFor({ - line: 1, - column: 1 - }); - assert.equal(mapping.source, "/the/root/one.js"); - map.destroy(); + map = await new SourceMapConsumer(util.testMap); + mapping = map.originalPositionFor({ + line: 2, + column: 1, + }); + assert.equal(mapping.source, "/the/root/two.js"); - map = await new SourceMapConsumer(util.testMapNoSourceRoot); + mapping = map.originalPositionFor({ + line: 1, + column: 1, + }); + assert.equal(mapping.source, "/the/root/one.js"); + map.destroy(); - mapping = map.originalPositionFor({ - line: 2, - column: 1 - }); - assert.equal(mapping.source, "two.js"); + map = await new SourceMapConsumer(util.testMapNoSourceRoot); - mapping = map.originalPositionFor({ - line: 1, - column: 1 - }); - assert.equal(mapping.source, "one.js"); - map.destroy(); + mapping = map.originalPositionFor({ + line: 2, + column: 1, + }); + assert.equal(mapping.source, "two.js"); + mapping = map.originalPositionFor({ + line: 1, + column: 1, + }); + assert.equal(mapping.source, "one.js"); + map.destroy(); - map = await new SourceMapConsumer(util.testMapEmptySourceRoot); + map = await new SourceMapConsumer(util.testMapEmptySourceRoot); - mapping = map.originalPositionFor({ - line: 2, - column: 1 - }); - assert.equal(mapping.source, "two.js"); + mapping = map.originalPositionFor({ + line: 2, + column: 1, + }); + assert.equal(mapping.source, "two.js"); - mapping = map.originalPositionFor({ - line: 1, - column: 1 - }); - assert.equal(mapping.source, "one.js"); - map.destroy(); -}; + mapping = map.originalPositionFor({ + line: 1, + column: 1, + }); + assert.equal(mapping.source, "one.js"); + map.destroy(); + }; -exports["test mapping tokens back exactly"] = async function(assert) { +exports["test mapping tokens back exactly"] = async function (assert) { const map = await new SourceMapConsumer(util.testMap); util.assertMapping(1, 1, "/the/root/one.js", 1, 1, null, null, map, assert); util.assertMapping(1, 5, "/the/root/one.js", 1, 5, null, null, map, assert); util.assertMapping(1, 9, "/the/root/one.js", 1, 11, null, null, map, assert); - util.assertMapping(1, 18, "/the/root/one.js", 1, 21, "bar", null, map, assert); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 21, + "bar", + null, + map, + assert + ); util.assertMapping(1, 21, "/the/root/one.js", 2, 3, null, null, map, assert); - util.assertMapping(1, 28, "/the/root/one.js", 2, 10, "baz", null, map, assert); - util.assertMapping(1, 32, "/the/root/one.js", 2, 14, "bar", null, map, assert); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 10, + "baz", + null, + map, + assert + ); + util.assertMapping( + 1, + 32, + "/the/root/one.js", + 2, + 14, + "bar", + null, + map, + assert + ); util.assertMapping(2, 1, "/the/root/two.js", 1, 1, null, null, map, assert); util.assertMapping(2, 5, "/the/root/two.js", 1, 5, null, null, map, assert); @@ -149,97 +201,466 @@ exports["test mapping tokens back exactly"] = async function(assert) { map.destroy(); }; -exports["test mapping tokens back exactly in indexed source map"] = async function(assert) { - const map = await new SourceMapConsumer(util.indexedTestMap); - - util.assertMapping(1, 1, "/the/root/one.js", 1, 1, null, null, map, assert); - util.assertMapping(1, 5, "/the/root/one.js", 1, 5, null, null, map, assert); - util.assertMapping(1, 9, "/the/root/one.js", 1, 11, null, null, map, assert); - util.assertMapping(1, 18, "/the/root/one.js", 1, 21, "bar", null, map, assert); - util.assertMapping(1, 21, "/the/root/one.js", 2, 3, null, null, map, assert); - util.assertMapping(1, 28, "/the/root/one.js", 2, 10, "baz", null, map, assert); - util.assertMapping(1, 32, "/the/root/one.js", 2, 14, "bar", null, map, assert); - - util.assertMapping(2, 1, "/the/root/two.js", 1, 1, null, null, map, assert); - util.assertMapping(2, 5, "/the/root/two.js", 1, 5, null, null, map, assert); - util.assertMapping(2, 9, "/the/root/two.js", 1, 11, null, null, map, assert); - util.assertMapping(2, 18, "/the/root/two.js", 1, 21, "n", null, map, assert); - util.assertMapping(2, 21, "/the/root/two.js", 2, 3, null, null, map, assert); - util.assertMapping(2, 28, "/the/root/two.js", 2, 10, "n", null, map, assert); - - map.destroy(); -}; +exports["test mapping tokens back exactly in indexed source map"] = + async function (assert) { + const map = await new SourceMapConsumer(util.indexedTestMap); + + util.assertMapping(1, 1, "/the/root/one.js", 1, 1, null, null, map, assert); + util.assertMapping(1, 5, "/the/root/one.js", 1, 5, null, null, map, assert); + util.assertMapping( + 1, + 9, + "/the/root/one.js", + 1, + 11, + null, + null, + map, + assert + ); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 21, + "bar", + null, + map, + assert + ); + util.assertMapping( + 1, + 21, + "/the/root/one.js", + 2, + 3, + null, + null, + map, + assert + ); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 10, + "baz", + null, + map, + assert + ); + util.assertMapping( + 1, + 32, + "/the/root/one.js", + 2, + 14, + "bar", + null, + map, + assert + ); + + util.assertMapping(2, 1, "/the/root/two.js", 1, 1, null, null, map, assert); + util.assertMapping(2, 5, "/the/root/two.js", 1, 5, null, null, map, assert); + util.assertMapping( + 2, + 9, + "/the/root/two.js", + 1, + 11, + null, + null, + map, + assert + ); + util.assertMapping( + 2, + 18, + "/the/root/two.js", + 1, + 21, + "n", + null, + map, + assert + ); + util.assertMapping( + 2, + 21, + "/the/root/two.js", + 2, + 3, + null, + null, + map, + assert + ); + util.assertMapping( + 2, + 28, + "/the/root/two.js", + 2, + 10, + "n", + null, + map, + assert + ); + + map.destroy(); + }; -exports["test mapping tokens fuzzy"] = async function(assert) { +exports["test mapping tokens fuzzy"] = async function (assert) { const map = await new SourceMapConsumer(util.testMap); // Finding original positions with default (glb) bias. - util.assertMapping(1, 20, "/the/root/one.js", 1, 21, "bar", null, map, assert, true); - util.assertMapping(1, 30, "/the/root/one.js", 2, 10, "baz", null, map, assert, true); - util.assertMapping(2, 12, "/the/root/two.js", 1, 11, null, null, map, assert, true); + util.assertMapping( + 1, + 20, + "/the/root/one.js", + 1, + 21, + "bar", + null, + map, + assert, + true + ); + util.assertMapping( + 1, + 30, + "/the/root/one.js", + 2, + 10, + "baz", + null, + map, + assert, + true + ); + util.assertMapping( + 2, + 12, + "/the/root/two.js", + 1, + 11, + null, + null, + map, + assert, + true + ); // Finding original positions with lub bias. - util.assertMapping(1, 16, "/the/root/one.js", 1, 21, "bar", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); - util.assertMapping(1, 26, "/the/root/one.js", 2, 10, "baz", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); - util.assertMapping(2, 6, "/the/root/two.js", 1, 11, null, SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); + util.assertMapping( + 1, + 16, + "/the/root/one.js", + 1, + 21, + "bar", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); + util.assertMapping( + 1, + 26, + "/the/root/one.js", + 2, + 10, + "baz", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); + util.assertMapping( + 2, + 6, + "/the/root/two.js", + 1, + 11, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); // Finding generated positions with default (glb) bias. - util.assertMapping(1, 18, "/the/root/one.js", 1, 22, "bar", null, map, assert, null, true); - util.assertMapping(1, 28, "/the/root/one.js", 2, 13, "baz", null, map, assert, null, true); - util.assertMapping(2, 9, "/the/root/two.js", 1, 16, null, null, map, assert, null, true); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 22, + "bar", + null, + map, + assert, + null, + true + ); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 13, + "baz", + null, + map, + assert, + null, + true + ); + util.assertMapping( + 2, + 9, + "/the/root/two.js", + 1, + 16, + null, + null, + map, + assert, + null, + true + ); // Finding generated positions with lub bias. - util.assertMapping(1, 18, "/the/root/one.js", 1, 20, "bar", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); - util.assertMapping(1, 28, "/the/root/one.js", 2, 7, "baz", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); - util.assertMapping(2, 9, "/the/root/two.js", 1, 6, null, SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 20, + "bar", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 7, + "baz", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); + util.assertMapping( + 2, + 9, + "/the/root/two.js", + 1, + 6, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); map.destroy(); }; -exports["test mapping tokens fuzzy in indexed source map"] = async function(assert) { +exports["test mapping tokens fuzzy in indexed source map"] = async function ( + assert +) { const map = await new SourceMapConsumer(util.indexedTestMap); // Finding original positions with default (glb) bias. - util.assertMapping(1, 20, "/the/root/one.js", 1, 21, "bar", null, map, assert, true); - util.assertMapping(1, 30, "/the/root/one.js", 2, 10, "baz", null, map, assert, true); - util.assertMapping(2, 12, "/the/root/two.js", 1, 11, null, null, map, assert, true); + util.assertMapping( + 1, + 20, + "/the/root/one.js", + 1, + 21, + "bar", + null, + map, + assert, + true + ); + util.assertMapping( + 1, + 30, + "/the/root/one.js", + 2, + 10, + "baz", + null, + map, + assert, + true + ); + util.assertMapping( + 2, + 12, + "/the/root/two.js", + 1, + 11, + null, + null, + map, + assert, + true + ); // Finding original positions with lub bias. - util.assertMapping(1, 16, "/the/root/one.js", 1, 21, "bar", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); - util.assertMapping(1, 26, "/the/root/one.js", 2, 10, "baz", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); - util.assertMapping(2, 6, "/the/root/two.js", 1, 11, null, SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, true); + util.assertMapping( + 1, + 16, + "/the/root/one.js", + 1, + 21, + "bar", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); + util.assertMapping( + 1, + 26, + "/the/root/one.js", + 2, + 10, + "baz", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); + util.assertMapping( + 2, + 6, + "/the/root/two.js", + 1, + 11, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + true + ); // Finding generated positions with default (glb) bias. - util.assertMapping(1, 18, "/the/root/one.js", 1, 22, "bar", null, map, assert, null, true); - util.assertMapping(1, 28, "/the/root/one.js", 2, 13, "baz", null, map, assert, null, true); - util.assertMapping(2, 9, "/the/root/two.js", 1, 16, null, null, map, assert, null, true); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 22, + "bar", + null, + map, + assert, + null, + true + ); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 13, + "baz", + null, + map, + assert, + null, + true + ); + util.assertMapping( + 2, + 9, + "/the/root/two.js", + 1, + 16, + null, + null, + map, + assert, + null, + true + ); // Finding generated positions with lub bias. - util.assertMapping(1, 18, "/the/root/one.js", 1, 20, "bar", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); - util.assertMapping(1, 28, "/the/root/one.js", 2, 7, "baz", SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); - util.assertMapping(2, 9, "/the/root/two.js", 1, 6, null, SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); + util.assertMapping( + 1, + 18, + "/the/root/one.js", + 1, + 20, + "bar", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); + util.assertMapping( + 1, + 28, + "/the/root/one.js", + 2, + 7, + "baz", + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); + util.assertMapping( + 2, + 9, + "/the/root/two.js", + 1, + 6, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); map.destroy(); }; -exports["test mappings and end of lines"] = async function(assert) { +exports["test mappings and end of lines"] = async function (assert) { const smg = new SourceMapGenerator({ - file: "foo.js" + file: "foo.js", }); smg.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 1 }, - source: "bar.js" + source: "bar.js", }); smg.addMapping({ original: { line: 2, column: 2 }, generated: { line: 2, column: 2 }, - source: "bar.js" + source: "bar.js", }); smg.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 1 }, - source: "baz.js" + source: "baz.js", }); const map = await SourceMapConsumer.fromSourceMap(smg); @@ -251,27 +672,45 @@ exports["test mappings and end of lines"] = async function(assert) { util.assertMapping(1, 1, "bar.js", 2, 1, null, null, map, assert, null, true); // When finding generated positions with, mappings end at the end of the source. - util.assertMapping(null, null, "bar.js", 3, 1, null, SourceMapConsumer.LEAST_UPPER_BOUND, map, assert, null, true); + util.assertMapping( + null, + null, + "bar.js", + 3, + 1, + null, + SourceMapConsumer.LEAST_UPPER_BOUND, + map, + assert, + null, + true + ); map.destroy(); }; -exports["test creating source map consumers with )]}' prefix"] = async function(assert) { - const map = await new SourceMapConsumer(")]}'\n" + JSON.stringify(util.testMap)); - assert.ok(true); - map.destroy(); -}; +exports["test creating source map consumers with )]}' prefix"] = + async function (assert) { + const map = await new SourceMapConsumer( + ")]}'\n" + JSON.stringify(util.testMap) + ); + assert.ok(true); + map.destroy(); + }; -exports["test eachMapping"] = async function(assert) { +exports["test eachMapping"] = async function (assert) { let map; map = await new SourceMapConsumer(util.testMap); let previousLine = -Infinity; let previousColumn = -Infinity; - map.eachMapping(function(mapping) { + map.eachMapping(function (mapping) { assert.ok(mapping.generatedLine >= previousLine); - assert.ok(mapping.source === "/the/root/one.js" || mapping.source === "/the/root/two.js"); + assert.ok( + mapping.source === "/the/root/one.js" || + mapping.source === "/the/root/two.js" + ); if (mapping.generatedLine === previousLine) { assert.ok(mapping.generatedColumn >= previousColumn); @@ -284,30 +723,36 @@ exports["test eachMapping"] = async function(assert) { map.destroy(); map = await new SourceMapConsumer(util.testMapNoSourceRoot); - map.eachMapping(function(mapping) { + map.eachMapping(function (mapping) { assert.ok(mapping.source === "one.js" || mapping.source === "two.js"); }); map.destroy(); map = await new SourceMapConsumer(util.testMapEmptySourceRoot); - map.eachMapping(function(mapping) { + map.eachMapping(function (mapping) { assert.ok(mapping.source === "one.js" || mapping.source === "two.js"); }); map.destroy(); map = await new SourceMapConsumer(util.mapWithSourcelessMapping); - map.eachMapping(function(mapping) { - assert.ok(mapping.source === null || (typeof mapping.originalColumn === "number" && typeof mapping.originalLine === "number")); + map.eachMapping(function (mapping) { + assert.ok( + mapping.source === null || + (typeof mapping.originalColumn === "number" && + typeof mapping.originalLine === "number") + ); }); map.destroy(); }; -exports["test eachMapping for indexed source maps"] = async function(assert) { +exports["test eachMapping for indexed source maps"] = async function (assert) { const map = await new SourceMapConsumer(util.indexedTestMap); + map.computeColumnSpans(); let previousLine = -Infinity; let previousColumn = -Infinity; + let previousLastColumn = -Infinity; - map.eachMapping(function(mapping) { + map.eachMapping(function (mapping) { assert.ok(mapping.generatedLine >= previousLine); if (mapping.source) { @@ -316,243 +761,359 @@ exports["test eachMapping for indexed source maps"] = async function(assert) { if (mapping.generatedLine === previousLine) { assert.ok(mapping.generatedColumn >= previousColumn); + if (typeof previousLastColumn === "number") { + assert.ok(mapping.generatedColumn > previousLastColumn); + } previousColumn = mapping.generatedColumn; + previousLastColumn = mapping.lastGeneratedColumn; } else { previousLine = mapping.generatedLine; previousColumn = -Infinity; + previousLastColumn = -Infinity; } }); map.destroy(); }; -exports["test iterating over mappings in a different order"] = async function(assert) { +exports["test eachMapping for indexed source maps with column offsets"] = + async function (assert) { + const map = await new SourceMapConsumer(util.indexedTestMapColumnOffset); + map.computeColumnSpans(); + let previousLine = -Infinity; + let previousColumn = -Infinity; + let previousLastColumn = -Infinity; + + map.eachMapping(function (mapping) { + assert.ok(mapping.generatedLine >= previousLine); + + if (mapping.source) { + assert.equal(mapping.source.indexOf(util.testMap.sourceRoot), 0); + } + + if (mapping.generatedLine === previousLine) { + assert.ok(mapping.generatedColumn >= previousColumn); + if (typeof previousLastColumn === "number") { + assert.ok(mapping.generatedColumn > previousLastColumn); + } + previousColumn = mapping.generatedColumn; + previousLastColumn = mapping.lastGeneratedColumn; + } else { + previousLine = mapping.generatedLine; + previousColumn = -Infinity; + previousLastColumn = -Infinity; + } + }); + + map.destroy(); + }; + +exports["test iterating over mappings in a different order"] = async function ( + assert +) { const map = await new SourceMapConsumer(util.testMap); let previousLine = -Infinity; let previousColumn = -Infinity; let previousSource = ""; - map.eachMapping(function(mapping) { - assert.ok(mapping.source >= previousSource); + map.eachMapping( + function (mapping) { + assert.ok(mapping.source >= previousSource); - if (mapping.source === previousSource) { - assert.ok(mapping.originalLine >= previousLine); + if (mapping.source === previousSource) { + assert.ok(mapping.originalLine >= previousLine); - if (mapping.originalLine === previousLine) { - assert.ok(mapping.originalColumn >= previousColumn); - previousColumn = mapping.originalColumn; + if (mapping.originalLine === previousLine) { + assert.ok(mapping.originalColumn >= previousColumn); + previousColumn = mapping.originalColumn; + } else { + previousLine = mapping.originalLine; + previousColumn = -Infinity; + } } else { - previousLine = mapping.originalLine; + previousSource = mapping.source; + previousLine = -Infinity; previousColumn = -Infinity; } - } else { - previousSource = mapping.source; - previousLine = -Infinity; - previousColumn = -Infinity; - } - }, null, SourceMapConsumer.ORIGINAL_ORDER); + }, + null, + SourceMapConsumer.ORIGINAL_ORDER + ); map.destroy(); }; -exports["test iterating over mappings in a different order in indexed source maps"] = async function(assert) { +exports[ + "test iterating over mappings in a different order in indexed source maps" +] = async function (assert) { const map = await new SourceMapConsumer(util.indexedTestMap); let previousLine = -Infinity; let previousColumn = -Infinity; let previousSource = ""; - map.eachMapping(function(mapping) { - assert.ok(mapping.source >= previousSource); - - if (mapping.source === previousSource) { - assert.ok(mapping.originalLine >= previousLine); - - if (mapping.originalLine === previousLine) { - assert.ok(mapping.originalColumn >= previousColumn); - previousColumn = mapping.originalColumn; + map.eachMapping( + function (mapping) { + assert.ok(mapping.source >= previousSource); + + if (mapping.source === previousSource) { + assert.ok(mapping.originalLine >= previousLine); + + if (mapping.originalLine === previousLine) { + assert.ok(mapping.originalColumn >= previousColumn); + previousColumn = mapping.originalColumn; + } else { + previousLine = mapping.originalLine; + previousColumn = -Infinity; + } } else { - previousLine = mapping.originalLine; + previousSource = mapping.source; + previousLine = -Infinity; previousColumn = -Infinity; } - } else { - previousSource = mapping.source; - previousLine = -Infinity; - previousColumn = -Infinity; - } - }, null, SourceMapConsumer.ORIGINAL_ORDER); + }, + null, + SourceMapConsumer.ORIGINAL_ORDER + ); map.destroy(); }; -exports["test that we can set the context for `this` in eachMapping"] = async function(assert) { - const map = await new SourceMapConsumer(util.testMap); - const context = {}; - map.eachMapping(function() { - assert.equal(this, context); - }, context); - map.destroy(); -}; +exports["test that we can set the context for `this` in eachMapping"] = + async function (assert) { + const map = await new SourceMapConsumer(util.testMap); + const context = {}; + map.eachMapping(function () { + assert.equal(this, context); + }, context); + map.destroy(); + }; -exports["test that we can set the context for `this` in eachMapping in indexed source maps"] = async function(assert) { +exports[ + "test that we can set the context for `this` in eachMapping in indexed source maps" +] = async function (assert) { const map = await new SourceMapConsumer(util.indexedTestMap); const context = {}; - map.eachMapping(function() { + map.eachMapping(function () { assert.equal(this, context); }, context); map.destroy(); }; -exports["test that the `sourcesContent` field has the original sources"] = async function(assert) { - const map = await new SourceMapConsumer(util.testMapWithSourcesContent); - const sourcesContent = map.sourcesContent; - - assert.equal(sourcesContent[0], " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(sourcesContent[1], " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.equal(sourcesContent.length, 2); - - map.destroy(); -}; - -exports["test that we can get the original sources for the sources"] = async function(assert) { - const map = await new SourceMapConsumer(util.testMapWithSourcesContent); - const sources = map.sources; - - assert.equal(map.sourceContentFor(sources[0]), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor(sources[1]), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.equal(map.sourceContentFor("one.js"), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor("two.js"), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.throws(function() { - map.sourceContentFor(""); - }, Error); - assert.throws(function() { - map.sourceContentFor("/the/root/three.js"); - }, Error); - assert.throws(function() { - map.sourceContentFor("three.js"); - }, Error); +exports["test that the `sourcesContent` field has the original sources"] = + async function (assert) { + const map = await new SourceMapConsumer(util.testMapWithSourcesContent); + const sourcesContent = map.sourcesContent; + + assert.equal( + sourcesContent[0], + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + sourcesContent[1], + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.equal(sourcesContent.length, 2); + + map.destroy(); + }; - map.destroy(); -}; +exports["test that we can get the original sources for the sources"] = + async function (assert) { + const map = await new SourceMapConsumer(util.testMapWithSourcesContent); + const sources = map.sources; + + assert.equal( + map.sourceContentFor(sources[0]), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor(sources[1]), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.equal( + map.sourceContentFor("one.js"), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor("two.js"), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.throws(function () { + map.sourceContentFor(""); + }, Error); + assert.throws(function () { + map.sourceContentFor("/the/root/three.js"); + }, Error); + assert.throws(function () { + map.sourceContentFor("three.js"); + }, Error); + + map.destroy(); + }; -exports["test that we can get the original source content with relative source paths"] = async function(assert) { +exports[ + "test that we can get the original source content with relative source paths" +] = async function (assert) { const map = await new SourceMapConsumer(util.testMapRelativeSources); const sources = map.sources; - assert.equal(map.sourceContentFor(sources[0]), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor(sources[1]), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.equal(map.sourceContentFor("one.js"), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor("two.js"), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.throws(function() { + assert.equal( + map.sourceContentFor(sources[0]), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor(sources[1]), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.equal( + map.sourceContentFor("one.js"), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor("two.js"), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.throws(function () { map.sourceContentFor(""); }, Error); - assert.throws(function() { + assert.throws(function () { map.sourceContentFor("/the/root/three.js"); }, Error); - assert.throws(function() { + assert.throws(function () { map.sourceContentFor("three.js"); }, Error); map.destroy(); }; -exports["test that we can get the original source content for the sources on an indexed source map"] = async function(assert) { +exports[ + "test that we can get the original source content for the sources on an indexed source map" +] = async function (assert) { const map = await new SourceMapConsumer(util.indexedTestMap); const sources = map.sources; - assert.equal(map.sourceContentFor(sources[0]), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor(sources[1]), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.equal(map.sourceContentFor("one.js"), " ONE.foo = function (bar) {\n return baz(bar);\n };"); - assert.equal(map.sourceContentFor("two.js"), " TWO.inc = function (n) {\n return n + 1;\n };"); - assert.throws(function() { + assert.equal( + map.sourceContentFor(sources[0]), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor(sources[1]), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.equal( + map.sourceContentFor("one.js"), + " ONE.foo = function (bar) {\n return baz(bar);\n };" + ); + assert.equal( + map.sourceContentFor("two.js"), + " TWO.inc = function (n) {\n return n + 1;\n };" + ); + assert.throws(function () { map.sourceContentFor(""); }, Error); - assert.throws(function() { + assert.throws(function () { map.sourceContentFor("/the/root/three.js"); }, Error); - assert.throws(function() { + assert.throws(function () { map.sourceContentFor("three.js"); }, Error); map.destroy(); }; -exports["test hasContentsOfAllSources, single source with contents"] = async function(assert) { - // Has one source: foo.js (with contents). - const mapWithContents = new SourceMapGenerator(); - mapWithContents.addMapping({ source: "foo.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); - mapWithContents.setSourceContent("foo.js", "content of foo.js"); +exports["test hasContentsOfAllSources, single source with contents"] = + async function (assert) { + // Has one source: foo.js (with contents). + const mapWithContents = new SourceMapGenerator(); + mapWithContents.addMapping({ + source: "foo.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); + mapWithContents.setSourceContent("foo.js", "content of foo.js"); - const consumer = await new SourceMapConsumer(mapWithContents.toJSON()); - assert.ok(consumer.hasContentsOfAllSources()); - consumer.destroy(); -}; + const consumer = await new SourceMapConsumer(mapWithContents.toJSON()); + assert.ok(consumer.hasContentsOfAllSources()); + consumer.destroy(); + }; -exports["test hasContentsOfAllSources, single source without contents"] = async function(assert) { - // Has one source: foo.js (without contents). - const mapWithoutContents = new SourceMapGenerator(); - mapWithoutContents.addMapping({ source: "foo.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); - const consumer = await new SourceMapConsumer(mapWithoutContents.toJSON()); - assert.ok(!consumer.hasContentsOfAllSources()); - consumer.destroy(); -}; +exports["test hasContentsOfAllSources, single source without contents"] = + async function (assert) { + // Has one source: foo.js (without contents). + const mapWithoutContents = new SourceMapGenerator(); + mapWithoutContents.addMapping({ + source: "foo.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); + const consumer = await new SourceMapConsumer(mapWithoutContents.toJSON()); + assert.ok(!consumer.hasContentsOfAllSources()); + consumer.destroy(); + }; -exports["test hasContentsOfAllSources, two sources with contents"] = async function(assert) { - // Has two sources: foo.js (with contents) and bar.js (with contents). - const mapWithBothContents = new SourceMapGenerator(); - mapWithBothContents.addMapping({ source: "foo.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); - mapWithBothContents.addMapping({ source: "bar.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); - mapWithBothContents.setSourceContent("foo.js", "content of foo.js"); - mapWithBothContents.setSourceContent("bar.js", "content of bar.js"); - const consumer = await new SourceMapConsumer(mapWithBothContents.toJSON()); - assert.ok(consumer.hasContentsOfAllSources()); - consumer.destroy(); -}; +exports["test hasContentsOfAllSources, two sources with contents"] = + async function (assert) { + // Has two sources: foo.js (with contents) and bar.js (with contents). + const mapWithBothContents = new SourceMapGenerator(); + mapWithBothContents.addMapping({ + source: "foo.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); + mapWithBothContents.addMapping({ + source: "bar.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); + mapWithBothContents.setSourceContent("foo.js", "content of foo.js"); + mapWithBothContents.setSourceContent("bar.js", "content of bar.js"); + const consumer = await new SourceMapConsumer(mapWithBothContents.toJSON()); + assert.ok(consumer.hasContentsOfAllSources()); + consumer.destroy(); + }; -exports["test hasContentsOfAllSources, two sources one with and one without contents"] = async function(assert) { +exports[ + "test hasContentsOfAllSources, two sources one with and one without contents" +] = async function (assert) { // Has two sources: foo.js (with contents) and bar.js (without contents). const mapWithoutSomeContents = new SourceMapGenerator(); - mapWithoutSomeContents.addMapping({ source: "foo.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); - mapWithoutSomeContents.addMapping({ source: "bar.js", - original: { line: 1, column: 10 }, - generated: { line: 1, column: 10 } }); + mapWithoutSomeContents.addMapping({ + source: "foo.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); + mapWithoutSomeContents.addMapping({ + source: "bar.js", + original: { line: 1, column: 10 }, + generated: { line: 1, column: 10 }, + }); mapWithoutSomeContents.setSourceContent("foo.js", "content of foo.js"); const consumer = await new SourceMapConsumer(mapWithoutSomeContents.toJSON()); assert.ok(!consumer.hasContentsOfAllSources()); consumer.destroy(); }; -exports["test sourceRoot + generatedPositionFor"] = async function(assert) { +exports["test sourceRoot + generatedPositionFor"] = async function (assert) { let map = new SourceMapGenerator({ sourceRoot: "foo/bar", - file: "baz.js" + file: "baz.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "bang.coffee" + source: "bang.coffee", }); map.addMapping({ original: { line: 5, column: 5 }, generated: { line: 6, column: 6 }, - source: "bang.coffee" + source: "bang.coffee", }); - map = await new SourceMapConsumer(map.toString(), "http://example.com/"); // Should handle without sourceRoot. let pos = map.generatedPositionFor({ line: 1, column: 1, - source: "bang.coffee" + source: "bang.coffee", }); assert.equal(pos.line, 2); @@ -562,7 +1123,7 @@ exports["test sourceRoot + generatedPositionFor"] = async function(assert) { pos = map.generatedPositionFor({ line: 1, column: 1, - source: "foo/bar/bang.coffee" + source: "foo/bar/bang.coffee", }); assert.equal(pos.line, 2); @@ -572,7 +1133,7 @@ exports["test sourceRoot + generatedPositionFor"] = async function(assert) { pos = map.generatedPositionFor({ line: 1, column: 1, - source: "http://example.com/foo/bar/bang.coffee" + source: "http://example.com/foo/bar/bang.coffee", }); assert.equal(pos.line, 2); @@ -581,67 +1142,118 @@ exports["test sourceRoot + generatedPositionFor"] = async function(assert) { map.destroy(); }; -exports["test sourceRoot + generatedPositionFor for path above the root"] = async function(assert) { - let map = new SourceMapGenerator({ - sourceRoot: "foo/bar", - file: "baz.js" +exports["test sourceRoot + generatedPositionFor for path above the root"] = + async function (assert) { + let map = new SourceMapGenerator({ + sourceRoot: "foo/bar", + file: "baz.js", + }); + map.addMapping({ + original: { line: 1, column: 1 }, + generated: { line: 2, column: 2 }, + source: "../bang.coffee", + }); + + map = await new SourceMapConsumer(map.toString()); + + // Should handle with sourceRoot. + const pos = map.generatedPositionFor({ + line: 1, + column: 1, + source: "foo/bang.coffee", + }); + + assert.equal(pos.line, 2); + assert.equal(pos.column, 2); + + map.destroy(); + }; + +exports["test index map + generatedPositionFor"] = async function (assert) { + const map = await new SourceMapConsumer( + util.indexedTestMapColumnOffset, + "http://example.com/" + ); + map.computeColumnSpans(); + + let pos = map.generatedPositionFor({ + line: 1, + column: 11, + source: "one.js", }); - map.addMapping({ - original: { line: 1, column: 1 }, - generated: { line: 2, column: 2 }, - source: "../bang.coffee" + + assert.equal(pos.line, 1); + assert.equal(pos.column, 9); + assert.equal(pos.lastColumn, 17); + + pos = map.generatedPositionFor({ + line: 2, + column: 3, + source: "one.js", }); - map = await new SourceMapConsumer(map.toString()); + assert.equal(pos.line, 1); + assert.equal(pos.column, 21); + assert.equal(pos.lastColumn, 27); - // Should handle with sourceRoot. - const pos = map.generatedPositionFor({ + pos = map.generatedPositionFor({ line: 1, - column: 1, - source: "foo/bang.coffee" + column: 11, + source: "two.js", }); - assert.equal(pos.line, 2); - assert.equal(pos.column, 2); + assert.equal(pos.line, 1); + assert.equal(pos.column, 59); + assert.equal(pos.lastColumn, 67); + + pos = map.generatedPositionFor({ + line: 2, + column: 3, + source: "two.js", + }); + + assert.equal(pos.line, 1); + assert.equal(pos.column, 71); + assert.equal(pos.lastColumn, 77); map.destroy(); }; -exports["test allGeneratedPositionsFor for line"] = async function(assert) { +exports["test allGeneratedPositionsFor for line"] = async function (assert) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "bar.coffee" + source: "bar.coffee", }); map.addMapping({ original: { line: 2, column: 1 }, generated: { line: 3, column: 2 }, - source: "bar.coffee" + source: "bar.coffee", }); map.addMapping({ original: { line: 2, column: 2 }, generated: { line: 3, column: 3 }, - source: "bar.coffee" + source: "bar.coffee", }); map.addMapping({ original: { line: 3, column: 1 }, generated: { line: 4, column: 2 }, - source: "bar.coffee" + source: "bar.coffee", }); map = await new SourceMapConsumer(map.toString(), "http://example.com/"); let mappings = map.allGeneratedPositionsFor({ line: 2, - source: "bar.coffee" + source: "bar.coffee", }); assert.equal(mappings.length, 2); @@ -652,7 +1264,7 @@ exports["test allGeneratedPositionsFor for line"] = async function(assert) { mappings = map.allGeneratedPositionsFor({ line: 2, - source: "http://example.com/bar.coffee" + source: "http://example.com/bar.coffee", }); assert.equal(mappings.length, 2); @@ -664,31 +1276,33 @@ exports["test allGeneratedPositionsFor for line"] = async function(assert) { map.destroy(); }; -exports["test allGeneratedPositionsFor for line fuzzy"] = async function(assert) { +exports["test allGeneratedPositionsFor for line fuzzy"] = async function ( + assert +) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "bar.coffee" + source: "bar.coffee", }); map.addMapping({ original: { line: 3, column: 1 }, generated: { line: 4, column: 2 }, - source: "bar.coffee" + source: "bar.coffee", }); map = await new SourceMapConsumer(map.toString()); const mappings = map.allGeneratedPositionsFor({ line: 2, - source: "bar.coffee" + source: "bar.coffee", }); assert.equal(mappings.length, 1); @@ -698,15 +1312,17 @@ exports["test allGeneratedPositionsFor for line fuzzy"] = async function(assert) map.destroy(); }; -exports["test allGeneratedPositionsFor for empty source map"] = async function(assert) { +exports["test allGeneratedPositionsFor for empty source map"] = async function ( + assert +) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map = await new SourceMapConsumer(map.toString()); const mappings = map.allGeneratedPositionsFor({ line: 2, - source: "bar.coffee" + source: "bar.coffee", }); assert.equal(mappings.length, 0); @@ -714,19 +1330,19 @@ exports["test allGeneratedPositionsFor for empty source map"] = async function(a map.destroy(); }; -exports["test allGeneratedPositionsFor for column"] = async function(assert) { +exports["test allGeneratedPositionsFor for column"] = async function (assert) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 2 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 3 }, - source: "foo.coffee" + source: "foo.coffee", }); map = await new SourceMapConsumer(map.toString()); @@ -734,7 +1350,7 @@ exports["test allGeneratedPositionsFor for column"] = async function(assert) { const mappings = map.allGeneratedPositionsFor({ line: 1, column: 1, - source: "foo.coffee" + source: "foo.coffee", }); assert.equal(mappings.length, 2); @@ -746,19 +1362,21 @@ exports["test allGeneratedPositionsFor for column"] = async function(assert) { map.destroy(); }; -exports["test allGeneratedPositionsFor for column fuzzy"] = async function(assert) { +exports["test allGeneratedPositionsFor for column fuzzy"] = async function ( + assert +) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 2 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 3 }, - source: "foo.coffee" + source: "foo.coffee", }); map = await new SourceMapConsumer(map.toString()); @@ -766,7 +1384,7 @@ exports["test allGeneratedPositionsFor for column fuzzy"] = async function(asser const mappings = map.allGeneratedPositionsFor({ line: 1, column: 0, - source: "foo.coffee" + source: "foo.coffee", }); assert.equal(mappings.length, 2); @@ -778,67 +1396,133 @@ exports["test allGeneratedPositionsFor for column fuzzy"] = async function(asser map.destroy(); }; -exports["test allGeneratedPositionsFor for column on different line fuzzy"] = async function(assert) { - let map = new SourceMapGenerator({ - file: "generated.js" +exports["test allGeneratedPositionsFor for column on different line fuzzy"] = + async function (assert) { + let map = new SourceMapGenerator({ + file: "generated.js", + }); + map.addMapping({ + original: { line: 2, column: 1 }, + generated: { line: 2, column: 2 }, + source: "foo.coffee", + }); + map.addMapping({ + original: { line: 2, column: 1 }, + generated: { line: 2, column: 3 }, + source: "foo.coffee", + }); + + map = await new SourceMapConsumer(map.toString()); + + const mappings = map.allGeneratedPositionsFor({ + line: 1, + column: 0, + source: "foo.coffee", + }); + + assert.equal(mappings.length, 0); + + map.destroy(); + }; + +exports["test allGeneratedPositionsFor for index map"] = async function ( + assert +) { + const map = await new SourceMapConsumer(util.indexedTestMapColumnOffset); + map.computeColumnSpans(); + + let mappings = map.allGeneratedPositionsFor({ + line: 2, + column: 3, + source: "one.js", }); - map.addMapping({ - original: { line: 2, column: 1 }, - generated: { line: 2, column: 2 }, - source: "foo.coffee" + + assert.deepEqual(mappings, [ + { + line: 1, + column: 21, + lastColumn: 27, + }, + ]); + + mappings = map.allGeneratedPositionsFor({ + line: 2, + column: 14, + source: "one.js", }); - map.addMapping({ - original: { line: 2, column: 1 }, - generated: { line: 2, column: 3 }, - source: "foo.coffee" + + assert.deepEqual(mappings, [ + { + line: 1, + column: 32, + lastColumn: 49, + }, + ]); + + mappings = map.allGeneratedPositionsFor({ + line: 2, + column: 3, + source: "two.js", }); - map = await new SourceMapConsumer(map.toString()); + assert.deepEqual(mappings, [ + { + line: 1, + column: 71, + lastColumn: 77, + }, + ]); - const mappings = map.allGeneratedPositionsFor({ - line: 1, - column: 0, - source: "foo.coffee" + mappings = map.allGeneratedPositionsFor({ + line: 2, + column: 10, + source: "two.js", }); - assert.equal(mappings.length, 0); + assert.deepEqual(mappings, [ + { + line: 1, + column: 78, + lastColumn: Infinity, + }, + ]); map.destroy(); }; -exports["test computeColumnSpans"] = async function(assert) { +exports["test computeColumnSpans"] = async function (assert) { let map = new SourceMapGenerator({ - file: "generated.js" + file: "generated.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 1, column: 1 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 2, column: 1 }, generated: { line: 2, column: 1 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 2, column: 2 }, generated: { line: 2, column: 10 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 2, column: 3 }, generated: { line: 2, column: 20 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 3, column: 1 }, generated: { line: 3, column: 1 }, - source: "foo.coffee" + source: "foo.coffee", }); map.addMapping({ original: { line: 3, column: 2 }, generated: { line: 3, column: 2 }, - source: "foo.coffee" + source: "foo.coffee", }); map = await new SourceMapConsumer(map.toString()); @@ -847,7 +1531,7 @@ exports["test computeColumnSpans"] = async function(assert) { let mappings = map.allGeneratedPositionsFor({ line: 1, - source: "foo.coffee" + source: "foo.coffee", }); assert.equal(mappings.length, 1); @@ -855,7 +1539,7 @@ exports["test computeColumnSpans"] = async function(assert) { mappings = map.allGeneratedPositionsFor({ line: 2, - source: "foo.coffee" + source: "foo.coffee", }); assert.equal(mappings.length, 3); @@ -865,7 +1549,7 @@ exports["test computeColumnSpans"] = async function(assert) { mappings = map.allGeneratedPositionsFor({ line: 3, - source: "foo.coffee" + source: "foo.coffee", }); assert.equal(mappings.length, 2); @@ -875,15 +1559,15 @@ exports["test computeColumnSpans"] = async function(assert) { map.destroy(); }; -exports["test sourceRoot + originalPositionFor"] = async function(assert) { +exports["test sourceRoot + originalPositionFor"] = async function (assert) { let map = new SourceMapGenerator({ sourceRoot: "foo/bar", - file: "baz.js" + file: "baz.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "bang.coffee" + source: "bang.coffee", }); map = await new SourceMapConsumer(map.toString()); @@ -901,31 +1585,11 @@ exports["test sourceRoot + originalPositionFor"] = async function(assert) { map.destroy(); }; -exports["test github issue #56"] = async function(assert) { - let map = new SourceMapGenerator({ - sourceRoot: "http://", - file: "www.example.com/foo.js" - }); - map.addMapping({ - original: { line: 1, column: 1 }, - generated: { line: 2, column: 2 }, - source: "www.example.com/original.js" - }); - - map = await new SourceMapConsumer(map.toString()); - - const sources = map.sources; - assert.equal(sources.length, 1); - assert.equal(sources[0], "http://www.example.com/original.js"); - - map.destroy(); -}; - // Was github issue #43, but that's no longer valid. -exports["test source resolution with sourceMapURL"] = async function(assert) { +exports["test source resolution with sourceMapURL"] = async function (assert) { let map = new SourceMapGenerator({ sourceRoot: "", - file: "foo.js" + file: "foo.js", }); map.addMapping({ original: { line: 1, column: 1 }, @@ -936,43 +1600,51 @@ exports["test source resolution with sourceMapURL"] = async function(assert) { map = await new SourceMapConsumer(map.toString(), "http://cdn.example.com/"); const sources = map.sources; - assert.equal(sources.length, 1, - "Should only be one source."); - assert.equal(sources[0], "http://cdn.example.com/original.js", - "Should be joined with the source map URL."); + assert.equal(sources.length, 1, "Should only be one source."); + assert.equal( + sources[0], + "http://cdn.example.com/original.js", + "Should be joined with the source map URL." + ); map.destroy(); }; -exports["test sourceRoot prepending"] = async function(assert) { +exports["test sourceRoot prepending"] = async function (assert) { let map = new SourceMapGenerator({ sourceRoot: "http://example.com/foo/bar", - file: "foo.js" + file: "foo.js", }); map.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "/original.js" + source: "/original.js", }); map = await new SourceMapConsumer(map.toString()); const sources = map.sources; - assert.equal(sources.length, 1, - "Should only be one source."); - assert.equal(sources[0], "http://example.com/foo/bar/original.js", - "Source include the source root."); + assert.equal(sources.length, 1, "Should only be one source."); + assert.equal( + sources[0], + "http://example.com/foo/bar/original.js", + "Source include the source root." + ); map.destroy(); }; -exports["test indexed source map errors when sections are out of order by line"] = async function(assert) { +exports[ + "test indexed source map errors when sections are out of order by line" +] = async function (assert) { // Make a deep copy of the indexedTestMap - const misorderedIndexedTestMap = JSON.parse(JSON.stringify(util.indexedTestMap)); + const misorderedIndexedTestMap = JSON.parse( + JSON.stringify(util.indexedTestMap) + ); misorderedIndexedTestMap.sections[0].offset = { line: 2, - column: 0 + column: 0, }; let error; @@ -984,15 +1656,15 @@ exports["test indexed source map errors when sections are out of order by line"] assert.ok(error instanceof Error); }; -exports["test github issue #64"] = async function(assert) { +exports["test github issue #64"] = async function (assert) { const map = await new SourceMapConsumer({ - "version": 3, - "file": "foo.js", - "sourceRoot": "http://example.com/", - "sources": ["/a"], - "names": [], - "mappings": "AACA", - "sourcesContent": ["foo"] + version: 3, + file: "foo.js", + sourceRoot: "http://example.com/", + sources: ["/a"], + names: [], + mappings: "AACA", + sourcesContent: ["foo"], }); assert.equal(map.sourceContentFor("a"), "foo"); @@ -1001,32 +1673,40 @@ exports["test github issue #64"] = async function(assert) { map.destroy(); }; -exports["test full source content with sourceMapURL"] = async function(assert) { - const map = await new SourceMapConsumer({ - "version": 3, - "file": "foo.js", - "sourceRoot": "", - "sources": ["original.js"], - "names": [], - "mappings": "AACA", - "sourcesContent": ["yellow warbler"] - }, "http://cdn.example.com/"); - - assert.equal(map.sourceContentFor("http://cdn.example.com/original.js"), "yellow warbler", - "Source content should be found using full URL"); +exports["test full source content with sourceMapURL"] = async function ( + assert +) { + const map = await new SourceMapConsumer( + { + version: 3, + file: "foo.js", + sourceRoot: "", + sources: ["original.js"], + names: [], + mappings: "AACA", + sourcesContent: ["yellow warbler"], + }, + "http://cdn.example.com/" + ); + + assert.equal( + map.sourceContentFor("http://cdn.example.com/original.js"), + "yellow warbler", + "Source content should be found using full URL" + ); map.destroy(); }; -exports["test bug 885597"] = async function(assert) { +exports["test bug 885597"] = async function (assert) { const map = await new SourceMapConsumer({ - "version": 3, - "file": "foo.js", - "sourceRoot": "file:///Users/AlGore/Invented/The/Internet/", - "sources": ["/a"], - "names": [], - "mappings": "AACA", - "sourcesContent": ["foo"] + version: 3, + file: "foo.js", + sourceRoot: "file:///Users/AlGore/Invented/The/Internet/", + sources: ["/a"], + names: [], + mappings: "AACA", + sourcesContent: ["foo"], }); const s = map.sources[0]; @@ -1035,19 +1715,19 @@ exports["test bug 885597"] = async function(assert) { map.destroy(); }; -exports["test github issue #72, duplicate sources"] = async function(assert) { +exports["test github issue #72, duplicate sources"] = async function (assert) { const map = await new SourceMapConsumer({ - "version": 3, - "file": "foo.js", - "sources": ["source1.js", "source1.js", "source3.js"], - "names": [], - "mappings": ";EAAC;;IAEE;;MEEE", - "sourceRoot": "http://example.com/" + version: 3, + file: "foo.js", + sources: ["source1.js", "source1.js", "source3.js"], + names: [], + mappings: ";EAAC;;IAEE;;MEEE", + sourceRoot: "http://example.com/", }); let pos = map.originalPositionFor({ line: 2, - column: 2 + column: 2, }); assert.equal(pos.source, "http://example.com/source1.js"); assert.equal(pos.line, 1); @@ -1055,7 +1735,7 @@ exports["test github issue #72, duplicate sources"] = async function(assert) { pos = map.originalPositionFor({ line: 4, - column: 4 + column: 4, }); assert.equal(pos.source, "http://example.com/source1.js"); assert.equal(pos.line, 3); @@ -1063,7 +1743,7 @@ exports["test github issue #72, duplicate sources"] = async function(assert) { pos = map.originalPositionFor({ line: 6, - column: 6 + column: 6, }); assert.equal(pos.source, "http://example.com/source3.js"); assert.equal(pos.line, 5); @@ -1072,19 +1752,19 @@ exports["test github issue #72, duplicate sources"] = async function(assert) { map.destroy(); }; -exports["test github issue #72, duplicate names"] = async function(assert) { +exports["test github issue #72, duplicate names"] = async function (assert) { const map = await new SourceMapConsumer({ - "version": 3, - "file": "foo.js", - "sources": ["source.js"], - "names": ["name1", "name1", "name3"], - "mappings": ";EAACA;;IAEEA;;MAEEE", - "sourceRoot": "http://example.com/" + version: 3, + file: "foo.js", + sources: ["source.js"], + names: ["name1", "name1", "name3"], + mappings: ";EAACA;;IAEEA;;MAEEE", + sourceRoot: "http://example.com/", }); let pos = map.originalPositionFor({ line: 2, - column: 2 + column: 2, }); assert.equal(pos.name, "name1"); assert.equal(pos.line, 1); @@ -1092,7 +1772,7 @@ exports["test github issue #72, duplicate names"] = async function(assert) { pos = map.originalPositionFor({ line: 4, - column: 4 + column: 4, }); assert.equal(pos.name, "name1"); assert.equal(pos.line, 3); @@ -1100,7 +1780,7 @@ exports["test github issue #72, duplicate names"] = async function(assert) { pos = map.originalPositionFor({ line: 6, - column: 6 + column: 6, }); assert.equal(pos.name, "name3"); assert.equal(pos.line, 5); @@ -1109,21 +1789,21 @@ exports["test github issue #72, duplicate names"] = async function(assert) { map.destroy(); }; -exports["test SourceMapConsumer.fromSourceMap"] = async function(assert) { +exports["test SourceMapConsumer.fromSourceMap"] = async function (assert) { const smg = new SourceMapGenerator({ sourceRoot: "http://example.com/", - file: "foo.js" + file: "foo.js", }); smg.addMapping({ original: { line: 1, column: 1 }, generated: { line: 2, column: 2 }, - source: "bar.js" + source: "bar.js", }); smg.addMapping({ original: { line: 2, column: 2 }, generated: { line: 4, column: 4 }, source: "baz.js", - name: "dirtMcGirt" + name: "dirtMcGirt", }); smg.setSourceContent("baz.js", "baz.js content"); @@ -1137,7 +1817,7 @@ exports["test SourceMapConsumer.fromSourceMap"] = async function(assert) { let pos = smc.originalPositionFor({ line: 2, - column: 2 + column: 2, }); assert.equal(pos.line, 1); assert.equal(pos.column, 1); @@ -1147,14 +1827,14 @@ exports["test SourceMapConsumer.fromSourceMap"] = async function(assert) { pos = smc.generatedPositionFor({ line: 1, column: 1, - source: "http://example.com/bar.js" + source: "http://example.com/bar.js", }); assert.equal(pos.line, 2); assert.equal(pos.column, 2); pos = smc.originalPositionFor({ line: 4, - column: 4 + column: 4, }); assert.equal(pos.line, 2); assert.equal(pos.column, 2); @@ -1164,7 +1844,7 @@ exports["test SourceMapConsumer.fromSourceMap"] = async function(assert) { pos = smc.generatedPositionFor({ line: 2, column: 2, - source: "http://example.com/baz.js" + source: "http://example.com/baz.js", }); assert.equal(pos.line, 4); assert.equal(pos.column, 4); @@ -1172,18 +1852,18 @@ exports["test SourceMapConsumer.fromSourceMap"] = async function(assert) { smc.destroy(); }; -exports["test issue #191"] = async function(assert) { +exports["test issue #191"] = async function (assert) { const generator = new SourceMapGenerator({ file: "a.css" }); generator.addMapping({ - source: "b.css", + source: "b.css", original: { - line: 1, - column: 0 + line: 1, + column: 0, }, generated: { - line: 1, - column: 0 - } + line: 1, + column: 0, + }, }); // Create a SourceMapConsumer from the SourceMapGenerator, ... @@ -1192,43 +1872,48 @@ exports["test issue #191"] = async function(assert) { // throw. generator.toJSON(); - assert.ok(true, "Using a SourceMapGenerator again after creating a " + - "SourceMapConsumer from it should not throw"); + assert.ok( + true, + "Using a SourceMapGenerator again after creating a SourceMapConsumer from it should not throw" + ); consumer.destroy(); }; -exports["test sources where their prefix is the source root: issue #199"] = async function(assert) { - const testSourceMap = { - "version": 3, - "sources": ["/source/app/app/app.js"], - "names": ["System"], - "mappings": "AAAAA", - "file": "app/app.js", - "sourcesContent": ["'use strict';"], - "sourceRoot": "/source/" - }; - - const consumer = await new SourceMapConsumer(testSourceMap); - - function consumerHasSource(s) { - assert.ok(consumer.sourceContentFor(s)); - } +exports["test sources where their prefix is the source root: issue #199"] = + async function (assert) { + const testSourceMap = { + version: 3, + sources: ["/source/app/app/app.js"], + names: ["System"], + mappings: "AAAAA", + file: "app/app.js", + sourcesContent: ["'use strict';"], + sourceRoot: "/source/", + }; + + const consumer = await new SourceMapConsumer(testSourceMap); + + function consumerHasSource(s) { + assert.ok(consumer.sourceContentFor(s)); + } - consumer.sources.forEach(consumerHasSource); - testSourceMap.sources.forEach(consumerHasSource); + consumer.sources.forEach(consumerHasSource); + testSourceMap.sources.forEach(consumerHasSource); - consumer.destroy(); -}; + consumer.destroy(); + }; -exports["test sources where their prefix is the source root and the source root is a url: issue #199"] = async function(assert) { +exports[ + "test sources where their prefix is the source root and the source root is a url: issue #199" +] = async function (assert) { const testSourceMap = { - "version": 3, - "sources": ["http://example.com/source/app/app/app.js"], - "names": ["System"], - "mappings": "AAAAA", - "sourcesContent": ["'use strict';"], - "sourceRoot": "http://example.com/source/" + version: 3, + sources: ["http://example.com/source/app/app/app.js"], + names: ["System"], + mappings: "AAAAA", + sourcesContent: ["'use strict';"], + sourceRoot: "http://example.com/source/", }; const consumer = await new SourceMapConsumer(testSourceMap); @@ -1243,12 +1928,14 @@ exports["test sources where their prefix is the source root and the source root consumer.destroy(); }; -exports["test consuming names and sources that are numbers"] = async function(assert) { +exports["test consuming names and sources that are numbers"] = async function ( + assert +) { const testSourceMap = { - "version": 3, - "sources": [0], - "names": [1], - "mappings": "AAAAA", + version: 3, + sources: [0], + names: [1], + mappings: "AAAAA", }; const consumer = await new SourceMapConsumer(testSourceMap); @@ -1257,7 +1944,7 @@ exports["test consuming names and sources that are numbers"] = async function(as assert.equal(consumer.sources[0], "0"); let i = 0; - consumer.eachMapping(function(m) { + consumer.eachMapping(function (m) { i++; assert.equal(m.name, "1"); }); @@ -1266,112 +1953,145 @@ exports["test consuming names and sources that are numbers"] = async function(as consumer.destroy(); }; -exports["test non-normalized sourceRoot (from issue #227)"] = async function(assert) { +exports["test non-normalized sourceRoot (from issue #227)"] = async function ( + assert +) { const consumer = await new SourceMapConsumer({ version: 3, - sources: [ "index.js" ], + sources: ["index.js"], names: [], mappings: ";;AAAA,IAAI,OAAO,MAAP", file: "index.js", sourceRoot: "./src/", - sourcesContent: [ 'var name = "Mark"\n' ] + sourcesContent: ['var name = "Mark"\n'], + }); + assert.doesNotThrow(() => { + // Before the fix, this threw an exception. + consumer.sourceContentFor(consumer.sources[0]); }); - assert.equal(consumer.sourceRoot, "src/", "sourceRoot was normalized"); - // Before the fix, this threw an exception. - consumer.sourceContentFor(consumer.sources[0]); consumer.destroy(); }; -exports["test webpack URL resolution"] = async function(assert) { +exports["test webpack URL resolution"] = async function (assert) { const map = { version: 3, - sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"], + sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"], names: [], mappings: "CAAS", file: "static/js/manifest.b7cf97680f7a50fa150f.js", - sourceRoot: "" + sourceRoot: "", }; const consumer = await new SourceMapConsumer(map); assert.equal(consumer.sources.length, 1); - assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44"); + assert.equal( + consumer.sources[0], + "webpack:///webpack/bootstrap%2067e184f9679733298d44" + ); consumer.destroy(); }; -exports["test webpack URL resolution with sourceMapURL"] = async function(assert) { +exports["test webpack URL resolution with sourceMapURL"] = async function ( + assert +) { const map = { version: 3, - sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"], + sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"], names: [], mappings: "CAAS", file: "static/js/manifest.b7cf97680f7a50fa150f.js", - sourceRoot: "" + sourceRoot: "", }; - const consumer = await new SourceMapConsumer(map, "http://www.example.com/q.js.map"); + const consumer = await new SourceMapConsumer( + map, + "http://www.example.com/q.js.map" + ); assert.equal(consumer.sources.length, 1); - assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44"); + assert.equal( + consumer.sources[0], + "webpack:///webpack/bootstrap%2067e184f9679733298d44" + ); consumer.destroy(); }; -exports["test relative webpack URL resolution with sourceMapURL"] = async function(assert) { - const map = { - version: 3, - sources: ["webpack/bootstrap.js"], - names: [], - mappings: "CAAS", - file: "static/js/manifest.b7cf97680f7a50fa150f.js", - sourceRoot: "webpack:///" +exports["test relative webpack URL resolution with sourceMapURL"] = + async function (assert) { + const map = { + version: 3, + sources: ["webpack/bootstrap.js"], + names: [], + mappings: "CAAS", + file: "static/js/manifest.b7cf97680f7a50fa150f.js", + sourceRoot: "webpack:///", + }; + const consumer = await new SourceMapConsumer( + map, + "http://www.example.com/q.js.map" + ); + + assert.equal(consumer.sources.length, 1); + assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap.js"); + + consumer.destroy(); }; - const consumer = await new SourceMapConsumer(map, "http://www.example.com/q.js.map"); - - assert.equal(consumer.sources.length, 1); - assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap.js"); - - consumer.destroy(); -}; -exports["test basic URL resolution with sourceMapURL"] = async function(assert) { +exports["test basic URL resolution with sourceMapURL"] = async function ( + assert +) { const map = { version: 3, - sources: ["something.js"], + sources: ["something.js"], names: [], mappings: "CAAS", file: "static/js/manifest.b7cf97680f7a50fa150f.js", - sourceRoot: "src" + sourceRoot: "src", }; - const consumer = await new SourceMapConsumer(map, "http://www.example.com/x/q.js.map"); + const consumer = await new SourceMapConsumer( + map, + "http://www.example.com/x/q.js.map" + ); assert.equal(consumer.sources.length, 1); - assert.equal(consumer.sources[0], "http://www.example.com/x/src/something.js"); + assert.equal( + consumer.sources[0], + "http://www.example.com/x/src/something.js" + ); consumer.destroy(); }; -exports["test absolute sourceURL resolution with sourceMapURL"] = async function(assert) { - const map = { - version: 3, - sources: ["something.js"], - names: [], - mappings: "CAAS", - file: "static/js/manifest.b7cf97680f7a50fa150f.js", - sourceRoot: "http://www.example.com/src" +exports["test absolute sourceURL resolution with sourceMapURL"] = + async function (assert) { + const map = { + version: 3, + sources: ["something.js"], + names: [], + mappings: "CAAS", + file: "static/js/manifest.b7cf97680f7a50fa150f.js", + sourceRoot: "http://www.example.com/src", + }; + const consumer = await new SourceMapConsumer( + map, + "http://www.example.com/x/q.js.map" + ); + + assert.equal(consumer.sources.length, 1); + assert.equal( + consumer.sources[0], + "http://www.example.com/src/something.js" + ); + + consumer.destroy(); }; - const consumer = await new SourceMapConsumer(map, "http://www.example.com/x/q.js.map"); - - assert.equal(consumer.sources.length, 1); - assert.equal(consumer.sources[0], "http://www.example.com/src/something.js"); - - consumer.destroy(); -}; -exports["test line numbers > 2**32"] = async function(assert) { +exports["test line numbers > 2**32"] = async function (assert) { const map = await new SourceMapConsumer({ version: 3, - sources: ["something.js"], + sources: ["something.js"], names: [], mappings: "C+/////DAS", file: "foo.js", @@ -1389,10 +2109,10 @@ exports["test line numbers > 2**32"] = async function(assert) { map.destroy(); }; -exports["test line numbers < 0"] = async function(assert) { +exports["test line numbers < 0"] = async function (assert) { const map = await new SourceMapConsumer({ version: 3, - sources: ["something.js"], + sources: ["something.js"], names: [], mappings: "CDAS", file: "foo.js", @@ -1410,24 +2130,28 @@ exports["test line numbers < 0"] = async function(assert) { map.destroy(); }; -exports["test SourceMapConsumer.with"] = async function(assert) { +exports["test SourceMapConsumer.with"] = async function (assert) { let consumer = null; - const six = await SourceMapConsumer.with(util.testMap, null, async function(c) { - // Don't keep references to the consumer around at home, kids. - consumer = c; + const six = await SourceMapConsumer.with( + util.testMap, + null, + async function (c) { + // Don't keep references to the consumer around at home, kids. + consumer = c; - // We should properly treat the with callback as an async function. - await new Promise(r => setTimeout(r, 1)); + // We should properly treat the with callback as an async function. + await new Promise(r => setTimeout(r, 1)); - // Should not have parsed and allocated mappings yet. - assert.equal(c._mappingsPtr, 0); + // Should not have parsed and allocated mappings yet. + assert.equal(c._mappingsPtr, 0); - // Force the mappings to be parsed and assert that we allocated mappings. - c.eachMapping(_ => {}); - assert.ok(c._mappingsPtr != 0); + // Force the mappings to be parsed and assert that we allocated mappings. + c.eachMapping(_ => {}); + assert.ok(c._mappingsPtr != 0); - return 6; - }); + return 6; + } + ); // Yes, we can return values. assert.equal(six, 6); @@ -1436,12 +2160,14 @@ exports["test SourceMapConsumer.with"] = async function(assert) { assert.equal(consumer._mappingsPtr, 0); }; -exports["test SourceMapConsumer.with and exceptions"] = async function(assert) { +exports["test SourceMapConsumer.with and exceptions"] = async function ( + assert +) { let consumer = null; let error = null; try { - await SourceMapConsumer.with(util.testMap, null, async function(c) { + await SourceMapConsumer.with(util.testMap, null, async function (c) { consumer = c; assert.equal(c._mappingsPtr, 0); @@ -1457,3 +2183,12 @@ exports["test SourceMapConsumer.with and exceptions"] = async function(assert) { assert.equal(error, 6); assert.equal(consumer._mappingsPtr, 0); }; + +exports["test a mapping at the boundary of indexed source map offset"] = + async function (assert) { + const map = await new SourceMapConsumer( + util.indexedTestMapAtOffsetBoundary + ); + util.assertMapping(1, 0, "/the/root/one.js", 1, 0, null, null, map, assert); + map.destroy(); + }; diff --git a/test/test-source-map-generator.js b/test/test-source-map-generator.js index 383a828e..6cc69ed2 100644 --- a/test/test-source-map-generator.js +++ b/test/test-source-map-generator.js @@ -5,15 +5,17 @@ * http://opensource.org/licenses/BSD-3-Clause */ -const SourceMapGenerator = require("../lib/source-map-generator").SourceMapGenerator; -const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; +const SourceMapGenerator = + require("../lib/source-map-generator").SourceMapGenerator; +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; const SourceNode = require("../lib/source-node").SourceNode; const util = require("./util"); -exports["test some simple stuff"] = function(assert) { +exports["test some simple stuff"] = function (assert) { let map = new SourceMapGenerator({ file: "foo.js", - sourceRoot: "." + sourceRoot: ".", }).toJSON(); assert.ok("file" in map); assert.ok("sourceRoot" in map); @@ -23,175 +25,177 @@ exports["test some simple stuff"] = function(assert) { assert.ok(!("sourceRoot" in map)); }; -exports["test JSON serialization"] = function(assert) { +exports["test JSON serialization"] = function (assert) { const map = new SourceMapGenerator({ file: "foo.js", - sourceRoot: "." + sourceRoot: ".", }); assert.equal(map.toString(), JSON.stringify(map)); }; -exports["test adding mappings (case 1)"] = function(assert) { +exports["test adding mappings (case 1)"] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", - sourceRoot: "." + sourceRoot: ".", }); - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { map.addMapping({ - generated: { line: 1, column: 1 } + generated: { line: 1, column: 1 }, }); }); }; -exports["test adding mappings (case 2)"] = function(assert) { +exports["test adding mappings (case 2)"] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", - sourceRoot: "." + sourceRoot: ".", }); - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { map.addMapping({ generated: { line: 1, column: 1 }, source: "bar.js", - original: { line: 1, column: 1 } + original: { line: 1, column: 1 }, }); }); }; -exports["test adding mappings (case 3)"] = function(assert) { +exports["test adding mappings (case 3)"] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", - sourceRoot: "." + sourceRoot: ".", }); - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { map.addMapping({ generated: { line: 1, column: 1 }, source: "bar.js", original: { line: 1, column: 1 }, - name: "someToken" + name: "someToken", }); }); }; -exports["test adding mappings (invalid)"] = function(assert) { +exports["test adding mappings (invalid)"] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", - sourceRoot: "." + sourceRoot: ".", }); // Not enough info. - assert.throws(function() { + assert.throws(function () { map.addMapping({}); }, /"generated" is a required argument/); // Original file position, but no source. - assert.throws(function() { + assert.throws(function () { map.addMapping({ generated: { line: 1, column: 1 }, - original: { line: 1, column: 1 } + original: { line: 1, column: 1 }, }); }, /Invalid mapping/); }; -exports["test adding mappings with skipValidation"] = function(assert) { +exports["test adding mappings with skipValidation"] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", sourceRoot: ".", - skipValidation: true + skipValidation: true, }); // Not enough info, caught by `util.getArgs` - assert.throws(function() { + assert.throws(function () { map.addMapping({}); }, /"generated" is a required argument/); // Original file position, but no source. Not checked. - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { map.addMapping({ generated: { line: 1, column: 1 }, - original: { line: 1, column: 1 } + original: { line: 1, column: 1 }, }); }, /Invalid mapping/); }; -exports["test that the correct mappings are being generated"] = function(assert) { +exports["test that the correct mappings are being generated"] = function ( + assert +) { let map = new SourceMapGenerator({ file: "min.js", - sourceRoot: "/the/root" + sourceRoot: "/the/root", }); map.addMapping({ generated: { line: 1, column: 1 }, original: { line: 1, column: 1 }, - source: "one.js" + source: "one.js", }); map.addMapping({ generated: { line: 1, column: 5 }, original: { line: 1, column: 5 }, - source: "one.js" + source: "one.js", }); map.addMapping({ generated: { line: 1, column: 9 }, original: { line: 1, column: 11 }, - source: "one.js" + source: "one.js", }); map.addMapping({ generated: { line: 1, column: 18 }, original: { line: 1, column: 21 }, source: "one.js", - name: "bar" + name: "bar", }); map.addMapping({ generated: { line: 1, column: 21 }, original: { line: 2, column: 3 }, - source: "one.js" + source: "one.js", }); map.addMapping({ generated: { line: 1, column: 28 }, original: { line: 2, column: 10 }, source: "one.js", - name: "baz" + name: "baz", }); map.addMapping({ generated: { line: 1, column: 32 }, original: { line: 2, column: 14 }, source: "one.js", - name: "bar" + name: "bar", }); map.addMapping({ generated: { line: 2, column: 1 }, original: { line: 1, column: 1 }, - source: "two.js" + source: "two.js", }); map.addMapping({ generated: { line: 2, column: 5 }, original: { line: 1, column: 5 }, - source: "two.js" + source: "two.js", }); map.addMapping({ generated: { line: 2, column: 9 }, original: { line: 1, column: 11 }, - source: "two.js" + source: "two.js", }); map.addMapping({ generated: { line: 2, column: 18 }, original: { line: 1, column: 21 }, source: "two.js", - name: "n" + name: "n", }); map.addMapping({ generated: { line: 2, column: 21 }, original: { line: 2, column: 3 }, - source: "two.js" + source: "two.js", }); map.addMapping({ generated: { line: 2, column: 28 }, original: { line: 2, column: 10 }, source: "two.js", - name: "n" + name: "n", }); map = JSON.parse(map.toString()); @@ -199,38 +203,40 @@ exports["test that the correct mappings are being generated"] = function(assert) util.assertEqualMaps(assert, map, util.testMap); }; -exports["test that adding a mapping with an empty string name does not break generation"] = function(assert) { +exports[ + "test that adding a mapping with an empty string name does not break generation" +] = function (assert) { const map = new SourceMapGenerator({ file: "generated-foo.js", - sourceRoot: "." + sourceRoot: ".", }); map.addMapping({ generated: { line: 1, column: 1 }, source: "bar.js", original: { line: 1, column: 1 }, - name: "" + name: "", }); - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { JSON.parse(map.toString()); }); }; -exports["test that source content can be set"] = function(assert) { +exports["test that source content can be set"] = function (assert) { let map = new SourceMapGenerator({ file: "min.js", - sourceRoot: "/the/root" + sourceRoot: "/the/root", }); map.addMapping({ generated: { line: 1, column: 1 }, original: { line: 1, column: 1 }, - source: "one.js" + source: "one.js", }); map.addMapping({ generated: { line: 2, column: 1 }, original: { line: 1, column: 1 }, - source: "two.js" + source: "two.js", }); map.setSourceContent("one.js", "one file content"); @@ -241,49 +247,64 @@ exports["test that source content can be set"] = function(assert) { assert.equal(map.sourcesContent[1], null); }; -exports["test .fromSourceMap"] = async function(assert) { +exports["test .fromSourceMap"] = async function (assert) { const smc = await new SourceMapConsumer(util.testMap); const map = SourceMapGenerator.fromSourceMap(smc); smc.destroy(); util.assertEqualMaps(assert, map.toJSON(), util.testMap); }; -exports["test .fromSourceMap with sourcesContent"] = async function(assert) { +exports["test .fromSourceMap with sourcesContent"] = async function (assert) { const smc = await new SourceMapConsumer(util.testMapWithSourcesContent); const map = SourceMapGenerator.fromSourceMap(smc); smc.destroy(); util.assertEqualMaps(assert, map.toJSON(), util.testMapWithSourcesContent); }; -exports["test .fromSourceMap with single source"] = async function(assert) { +exports["test .fromSourceMap with single source"] = async function (assert) { const smc = await new SourceMapConsumer(util.testMapSingleSource); const map = SourceMapGenerator.fromSourceMap(smc); smc.destroy(); util.assertEqualMaps(assert, map.toJSON(), util.testMapSingleSource); }; -exports["test .fromSourceMap with empty mappings"] = async function(assert) { +exports["test .fromSourceMap with empty mappings"] = async function (assert) { const smc = await new SourceMapConsumer(util.testMapEmptyMappings); const map = SourceMapGenerator.fromSourceMap(smc); smc.destroy(); util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappings); }; -exports["test .fromSourceMap with empty mappings and relative sources"] = async function(assert) { - const smc = await new SourceMapConsumer(util.testMapEmptyMappingsRelativeSources); - const map = SourceMapGenerator.fromSourceMap(smc); - smc.destroy(); - util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappingsRelativeSources_generatedExpected); -}; +exports["test .fromSourceMap with empty mappings and relative sources"] = + async function (assert) { + const smc = await new SourceMapConsumer( + util.testMapEmptyMappingsRelativeSources + ); + const map = SourceMapGenerator.fromSourceMap(smc); + smc.destroy(); + util.assertEqualMaps( + assert, + map.toJSON(), + util.testMapEmptyMappingsRelativeSources_generatedExpected + ); + }; -exports["test .fromSourceMap with multiple sources where mappings refers only to single source"] = async function(assert) { - const smc = await new SourceMapConsumer(util.testMapMultiSourcesMappingRefersSingleSourceOnly); +exports[ + "test .fromSourceMap with multiple sources where mappings refers only to single source" +] = async function (assert) { + const smc = await new SourceMapConsumer( + util.testMapMultiSourcesMappingRefersSingleSourceOnly + ); const map = SourceMapGenerator.fromSourceMap(smc); smc.destroy(); - util.assertEqualMaps(assert, map.toJSON(), util.testMapMultiSourcesMappingRefersSingleSourceOnly); + util.assertEqualMaps( + assert, + map.toJSON(), + util.testMapMultiSourcesMappingRefersSingleSourceOnly + ); }; -exports["test applySourceMap"] = async function(assert) { +exports["test applySourceMap"] = async function (assert) { let node = new SourceNode(null, null, null, [ new SourceNode(2, 0, "fileX", "lineX2\n"), "genA1\n", @@ -291,10 +312,10 @@ exports["test applySourceMap"] = async function(assert) { "genA2\n", new SourceNode(1, 0, "fileX", "lineX1\n"), "genA3\n", - new SourceNode(1, 0, "fileY", "lineY1\n") + new SourceNode(1, 0, "fileY", "lineY1\n"), ]); let mapStep1 = node.toStringWithSourceMap({ - file: "fileA" + file: "fileA", }).map; mapStep1.setSourceContent("fileX", "lineX1\nlineX2\n"); mapStep1 = mapStep1.toJSON(); @@ -307,10 +328,10 @@ exports["test applySourceMap"] = async function(assert) { new SourceNode(4, 0, "fileA", "lineA4\n"), new SourceNode(1, 0, "fileB", "lineB1\n"), new SourceNode(2, 0, "fileB", "lineB2\n"), - "gen2\n" + "gen2\n", ]); let mapStep2 = node.toStringWithSourceMap({ - file: "fileGen" + file: "fileGen", }).map; mapStep2.setSourceContent("fileB", "lineB1\nlineB2\n"); mapStep2 = mapStep2.toJSON(); @@ -323,10 +344,10 @@ exports["test applySourceMap"] = async function(assert) { new SourceNode(4, 0, "fileA", "lineA4\n"), new SourceNode(1, 0, "fileB", "lineB1\n"), new SourceNode(2, 0, "fileB", "lineB2\n"), - "gen2\n" + "gen2\n", ]); let expectedMap = node.toStringWithSourceMap({ - file: "fileGen" + file: "fileGen", }).map; expectedMap.setSourceContent("fileX", "lineX1\nlineX2\n"); expectedMap.setSourceContent("fileB", "lineB1\nlineB2\n"); @@ -345,9 +366,11 @@ exports["test applySourceMap"] = async function(assert) { util.assertEqualMaps(assert, actualMap, expectedMap); }; -exports["test applySourceMap throws when file is missing"] = async function(assert) { +exports["test applySourceMap throws when file is missing"] = async function ( + assert +) { const map = new SourceMapGenerator({ - file: "test.js" + file: "test.js", }); const map2 = new SourceMapGenerator(); @@ -363,178 +386,207 @@ exports["test applySourceMap throws when file is missing"] = async function(asse assert.ok(error instanceof Error); }; -exports["test the two additional parameters of applySourceMap"] = async function(assert) { - // Assume the following directory structure: - // - // http://foo.org/ - // bar.coffee - // app/ - // coffee/ - // foo.coffee - // temp/ - // bundle.js - // temp_maps/ - // bundle.js.map - // public/ - // bundle.min.js - // bundle.min.js.map - // - // http://www.example.com/ - // baz.coffee - - let bundleMap = new SourceMapGenerator({ - file: "bundle.js" - }); - bundleMap.addMapping({ - generated: { line: 3, column: 3 }, - original: { line: 2, column: 2 }, - source: "../../coffee/foo.coffee" - }); - bundleMap.setSourceContent("../../coffee/foo.coffee", "foo coffee"); - bundleMap.addMapping({ - generated: { line: 13, column: 13 }, - original: { line: 12, column: 12 }, - source: "/bar.coffee" - }); - bundleMap.setSourceContent("/bar.coffee", "bar coffee"); - bundleMap.addMapping({ - generated: { line: 23, column: 23 }, - original: { line: 22, column: 22 }, - source: "http://www.example.com/baz.coffee" - }); - bundleMap.setSourceContent( - "http://www.example.com/baz.coffee", - "baz coffee" - ); - bundleMap = await new SourceMapConsumer(bundleMap.toJSON()); - - let minifiedMap = new SourceMapGenerator({ - file: "bundle.min.js", - sourceRoot: ".." - }); - minifiedMap.addMapping({ - generated: { line: 1, column: 1 }, - original: { line: 3, column: 3 }, - source: "temp/bundle.js" - }); - minifiedMap.addMapping({ - generated: { line: 11, column: 11 }, - original: { line: 13, column: 13 }, - source: "temp/bundle.js" - }); - minifiedMap.addMapping({ - generated: { line: 21, column: 21 }, - original: { line: 23, column: 23 }, - source: "temp/bundle.js" - }); - minifiedMap = await new SourceMapConsumer(minifiedMap.toJSON()); +exports["test the two additional parameters of applySourceMap"] = + async function (assert) { + // Assume the following directory structure: + // + // http://foo.org/ + // bar.coffee + // app/ + // coffee/ + // foo.coffee + // temp/ + // bundle.js + // temp_maps/ + // bundle.js.map + // public/ + // bundle.min.js + // bundle.min.js.map + // + // http://www.example.com/ + // baz.coffee + + let bundleMap = new SourceMapGenerator({ + file: "bundle.js", + }); + bundleMap.addMapping({ + generated: { line: 3, column: 3 }, + original: { line: 2, column: 2 }, + source: "../../coffee/foo.coffee", + }); + bundleMap.setSourceContent("../../coffee/foo.coffee", "foo coffee"); + bundleMap.addMapping({ + generated: { line: 13, column: 13 }, + original: { line: 12, column: 12 }, + source: "/bar.coffee", + }); + bundleMap.setSourceContent("/bar.coffee", "bar coffee"); + bundleMap.addMapping({ + generated: { line: 23, column: 23 }, + original: { line: 22, column: 22 }, + source: "http://www.example.com/baz.coffee", + }); + bundleMap.setSourceContent( + "http://www.example.com/baz.coffee", + "baz coffee" + ); + bundleMap = await new SourceMapConsumer(bundleMap.toJSON()); - const expectedMap = function(sources) { - const map = new SourceMapGenerator({ + let minifiedMap = new SourceMapGenerator({ file: "bundle.min.js", - sourceRoot: ".." + sourceRoot: "..", }); - map.addMapping({ + minifiedMap.addMapping({ generated: { line: 1, column: 1 }, - original: { line: 2, column: 2 }, - source: sources[0] + original: { line: 3, column: 3 }, + source: "temp/bundle.js", }); - map.setSourceContent(sources[0], "foo coffee"); - map.addMapping({ + minifiedMap.addMapping({ generated: { line: 11, column: 11 }, - original: { line: 12, column: 12 }, - source: sources[1] + original: { line: 13, column: 13 }, + source: "temp/bundle.js", }); - map.setSourceContent(sources[1], "bar coffee"); - map.addMapping({ + minifiedMap.addMapping({ generated: { line: 21, column: 21 }, - original: { line: 22, column: 22 }, - source: sources[2] + original: { line: 23, column: 23 }, + source: "temp/bundle.js", }); - map.setSourceContent(sources[2], "baz coffee"); - return map.toJSON(); + minifiedMap = await new SourceMapConsumer(minifiedMap.toJSON()); + + const expectedMap = function (sources) { + const map = new SourceMapGenerator({ + file: "bundle.min.js", + sourceRoot: "..", + }); + map.addMapping({ + generated: { line: 1, column: 1 }, + original: { line: 2, column: 2 }, + source: sources[0], + }); + map.setSourceContent(sources[0], "foo coffee"); + map.addMapping({ + generated: { line: 11, column: 11 }, + original: { line: 12, column: 12 }, + source: sources[1], + }); + map.setSourceContent(sources[1], "bar coffee"); + map.addMapping({ + generated: { line: 21, column: 21 }, + original: { line: 22, column: 22 }, + source: sources[2], + }); + map.setSourceContent(sources[2], "baz coffee"); + return map.toJSON(); + }; + + const actualMap = function (aSourceMapPath) { + const map = SourceMapGenerator.fromSourceMap(minifiedMap); + // Note that relying on `bundleMap.file` (which is simply 'bundle.js') + // instead of supplying the second parameter wouldn't work here. + map.applySourceMap(bundleMap, "../temp/bundle.js", aSourceMapPath); + return map.toJSON(); + }; + + util.assertEqualMaps( + assert, + actualMap("../temp/temp_maps"), + expectedMap([ + "coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + util.assertEqualMaps( + assert, + actualMap("/app/temp/temp_maps"), + expectedMap([ + "/app/coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + util.assertEqualMaps( + assert, + actualMap("http://foo.org/app/temp/temp_maps"), + expectedMap([ + "http://foo.org/app/coffee/foo.coffee", + "http://foo.org/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + // If the third parameter is omitted or set to the current working + // directory we get incorrect source paths: + + util.assertEqualMaps( + assert, + actualMap(), + expectedMap([ + "../coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + util.assertEqualMaps( + assert, + actualMap(""), + expectedMap([ + "../coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + util.assertEqualMaps( + assert, + actualMap("."), + expectedMap([ + "../coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + util.assertEqualMaps( + assert, + actualMap("./"), + expectedMap([ + "../coffee/foo.coffee", + "/bar.coffee", + "http://www.example.com/baz.coffee", + ]) + ); + + bundleMap.destroy(); + minifiedMap.destroy(); }; - const actualMap = function(aSourceMapPath) { - const map = SourceMapGenerator.fromSourceMap(minifiedMap); - // Note that relying on `bundleMap.file` (which is simply 'bundle.js') - // instead of supplying the second parameter wouldn't work here. - map.applySourceMap(bundleMap, "../temp/bundle.js", aSourceMapPath); - return map.toJSON(); - }; - - util.assertEqualMaps(assert, actualMap("../temp/temp_maps"), expectedMap([ - "coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - util.assertEqualMaps(assert, actualMap("/app/temp/temp_maps"), expectedMap([ - "/app/coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - util.assertEqualMaps(assert, actualMap("http://foo.org/app/temp/temp_maps"), expectedMap([ - "http://foo.org/app/coffee/foo.coffee", - "http://foo.org/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - // If the third parameter is omitted or set to the current working - // directory we get incorrect source paths: - - util.assertEqualMaps(assert, actualMap(), expectedMap([ - "../coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - util.assertEqualMaps(assert, actualMap(""), expectedMap([ - "../coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - util.assertEqualMaps(assert, actualMap("."), expectedMap([ - "../coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - util.assertEqualMaps(assert, actualMap("./"), expectedMap([ - "../coffee/foo.coffee", - "/bar.coffee", - "http://www.example.com/baz.coffee" - ])); - - bundleMap.destroy(); - minifiedMap.destroy(); -}; - -exports["test applySourceMap name handling"] = async function(assert) { +exports["test applySourceMap name handling"] = async function (assert) { // Imagine some CoffeeScript code being compiled into JavaScript and then // minified. - const assertName = async function(coffeeName, jsName, expectedName) { + const assertName = async function (coffeeName, jsName, expectedName) { const minifiedMap = new SourceMapGenerator({ - file: "test.js.min" + file: "test.js.min", }); minifiedMap.addMapping({ generated: { line: 1, column: 4 }, original: { line: 1, column: 4 }, source: "test.js", - name: jsName + name: jsName, }); const coffeeMap = new SourceMapGenerator({ - file: "test.js" + file: "test.js", }); coffeeMap.addMapping({ generated: { line: 1, column: 4 }, original: { line: 1, column: 0 }, source: "test.coffee", - name: coffeeName + name: coffeeName, }); let consumer = await new SourceMapConsumer(coffeeMap.toJSON()); @@ -542,7 +594,7 @@ exports["test applySourceMap name handling"] = async function(assert) { consumer.destroy(); consumer = await new SourceMapConsumer(minifiedMap.toJSON()); - consumer.eachMapping(function(mapping) { + consumer.eachMapping(function (mapping) { assert.equal(mapping.name, expectedName); }); consumer.destroy(); @@ -572,25 +624,25 @@ exports["test applySourceMap name handling"] = async function(assert) { await assertName(null, null, null); }; -exports["test sorting with duplicate generated mappings"] = function(assert) { +exports["test sorting with duplicate generated mappings"] = function (assert) { const map = new SourceMapGenerator({ - file: "test.js" + file: "test.js", }); map.addMapping({ generated: { line: 3, column: 0 }, original: { line: 2, column: 0 }, - source: "a.js" + source: "a.js", }); map.addMapping({ - generated: { line: 2, column: 0 } + generated: { line: 2, column: 0 }, }); map.addMapping({ - generated: { line: 2, column: 0 } + generated: { line: 2, column: 0 }, }); map.addMapping({ generated: { line: 1, column: 0 }, original: { line: 1, column: 0 }, - source: "a.js" + source: "a.js", }); util.assertEqualMaps(assert, map.toJSON(), { @@ -598,20 +650,20 @@ exports["test sorting with duplicate generated mappings"] = function(assert) { file: "test.js", sources: ["a.js"], names: [], - mappings: "AAAA;A;AACA" + mappings: "AAAA;A;AACA", }); }; -exports["test ignore duplicate mappings."] = function(assert) { +exports["test ignore duplicate mappings."] = function (assert) { const init = { file: "min.js", sourceRoot: "/the/root" }; let map1, map2; // null original source location const nullMapping1 = { - generated: { line: 1, column: 0 } + generated: { line: 1, column: 0 }, }; const nullMapping2 = { - generated: { line: 2, column: 2 } + generated: { line: 2, column: 2 }, }; map1 = new SourceMapGenerator(init); @@ -635,12 +687,12 @@ exports["test ignore duplicate mappings."] = function(assert) { const srcMapping1 = { generated: { line: 1, column: 0 }, original: { line: 11, column: 0 }, - source: "srcMapping1.js" + source: "srcMapping1.js", }; const srcMapping2 = { generated: { line: 2, column: 2 }, original: { line: 11, column: 0 }, - source: "srcMapping2.js" + source: "srcMapping2.js", }; map1 = new SourceMapGenerator(init); @@ -665,13 +717,13 @@ exports["test ignore duplicate mappings."] = function(assert) { generated: { line: 1, column: 0 }, original: { line: 11, column: 0 }, source: "fullMapping1.js", - name: "fullMapping1" + name: "fullMapping1", }; const fullMapping2 = { generated: { line: 2, column: 2 }, original: { line: 11, column: 0 }, source: "fullMapping2.js", - name: "fullMapping2" + name: "fullMapping2", }; map1 = new SourceMapGenerator(init); @@ -692,74 +744,77 @@ exports["test ignore duplicate mappings."] = function(assert) { util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON()); }; -exports["test github issue #72, check for duplicate names or sources"] = function(assert) { - const map = new SourceMapGenerator({ - file: "test.js" - }); - map.addMapping({ - generated: { line: 1, column: 1 }, - original: { line: 2, column: 2 }, - source: "a.js", - name: "foo" - }); - map.addMapping({ - generated: { line: 3, column: 3 }, - original: { line: 4, column: 4 }, - source: "a.js", - name: "foo" - }); - util.assertEqualMaps(assert, map.toJSON(), { - version: 3, - file: "test.js", - sources: ["a.js"], - names: ["foo"], - mappings: "CACEA;;GAEEA" - }); -}; +exports["test github issue #72, check for duplicate names or sources"] = + function (assert) { + const map = new SourceMapGenerator({ + file: "test.js", + }); + map.addMapping({ + generated: { line: 1, column: 1 }, + original: { line: 2, column: 2 }, + source: "a.js", + name: "foo", + }); + map.addMapping({ + generated: { line: 3, column: 3 }, + original: { line: 4, column: 4 }, + source: "a.js", + name: "foo", + }); + util.assertEqualMaps(assert, map.toJSON(), { + version: 3, + file: "test.js", + sources: ["a.js"], + names: ["foo"], + mappings: "CACEA;;GAEEA", + }); + }; -exports["test setting sourcesContent to null when already null"] = function(assert) { +exports["test setting sourcesContent to null when already null"] = function ( + assert +) { const smg = new SourceMapGenerator({ file: "foo.js" }); - assert.doesNotThrow(function() { + assert.doesNotThrow(function () { smg.setSourceContent("bar.js", null); }); }; -exports["test applySourceMap with unexact match"] = async function(assert) { +exports["test applySourceMap with unexact match"] = async function (assert) { const map1 = new SourceMapGenerator({ - file: "bundled-source" + file: "bundled-source", }); map1.addMapping({ generated: { line: 1, column: 4 }, original: { line: 1, column: 4 }, - source: "transformed-source" + source: "transformed-source", }); map1.addMapping({ generated: { line: 2, column: 4 }, original: { line: 2, column: 4 }, - source: "transformed-source" + source: "transformed-source", }); const map2 = new SourceMapGenerator({ - file: "transformed-source" + file: "transformed-source", }); map2.addMapping({ generated: { line: 2, column: 0 }, original: { line: 1, column: 0 }, - source: "original-source" + source: "original-source", }); const expectedMap = new SourceMapGenerator({ - file: "bundled-source" + file: "bundled-source", }); expectedMap.addMapping({ generated: { line: 1, column: 4 }, original: { line: 1, column: 4 }, - source: "transformed-source" + source: "transformed-source", }); expectedMap.addMapping({ generated: { line: 2, column: 4 }, original: { line: 1, column: 0 }, - source: "original-source" + source: "original-source", }); const consumer = await new SourceMapConsumer(map2.toJSON()); @@ -769,9 +824,9 @@ exports["test applySourceMap with unexact match"] = async function(assert) { util.assertEqualMaps(assert, map1.toJSON(), expectedMap.toJSON()); }; -exports["test applySourceMap with empty mappings"] = async function(assert) { +exports["test applySourceMap with empty mappings"] = async function (assert) { let consumer = await new SourceMapConsumer(util.testMapEmptyMappings); - const generator = SourceMapGenerator.fromSourceMap(consumer); + const generator = SourceMapGenerator.fromSourceMap(consumer); consumer.destroy(); consumer = await new SourceMapConsumer(util.testMapEmptyMappings); @@ -781,19 +836,28 @@ exports["test applySourceMap with empty mappings"] = async function(assert) { util.assertEqualMaps(assert, generator.toJSON(), util.testMapEmptyMappings); }; -exports["test applySourceMap with empty mappings and relative sources"] = async function(assert) { - let consumer = await new SourceMapConsumer(util.testMapEmptyMappingsRelativeSources); - const generator = SourceMapGenerator.fromSourceMap(consumer); - consumer.destroy(); +exports["test applySourceMap with empty mappings and relative sources"] = + async function (assert) { + let consumer = await new SourceMapConsumer( + util.testMapEmptyMappingsRelativeSources + ); + const generator = SourceMapGenerator.fromSourceMap(consumer); + consumer.destroy(); - consumer = await new SourceMapConsumer(util.testMapEmptyMappingsRelativeSources); - generator.applySourceMap(consumer); - consumer.destroy(); + consumer = await new SourceMapConsumer( + util.testMapEmptyMappingsRelativeSources + ); + generator.applySourceMap(consumer); + consumer.destroy(); - util.assertEqualMaps(assert, generator.toJSON(), util.testMapEmptyMappingsRelativeSources_generatedExpected); -}; + util.assertEqualMaps( + assert, + generator.toJSON(), + util.testMapEmptyMappingsRelativeSources_generatedExpected + ); + }; -exports["test issue #192"] = async function(assert) { +exports["test issue #192"] = async function (assert) { const generator = new SourceMapGenerator(); generator.addMapping({ source: "a.js", @@ -809,22 +873,26 @@ exports["test issue #192"] = async function(assert) { const consumer = await new SourceMapConsumer(generator.toJSON()); let n = 0; - consumer.eachMapping(function() { n++; }); + consumer.eachMapping(function () { + n++; + }); - assert.equal(n, 2, - "Should not de-duplicate mappings that have the same " + - "generated positions, but different original positions."); + assert.equal( + n, + 2, + "Should not de-duplicate mappings that have the same generated positions, but different original positions." + ); consumer.destroy(); }; -exports["test numeric names #231"] = function(assert) { +exports["test numeric names #231"] = function (assert) { const generator = new SourceMapGenerator(); generator.addMapping({ source: "a.js", generated: { line: 1, column: 10 }, original: { line: 1, column: 10 }, - name: 8 + name: 8, }); const map = generator.toJSON(); assert.ok(map, "Adding a mapping with a numeric name did not throw"); diff --git a/test/test-source-node.js b/test/test-source-node.js index 337952c3..6098ba23 100644 --- a/test/test-source-node.js +++ b/test/test-source-node.js @@ -6,18 +6,20 @@ */ const util = require("./util"); -const SourceMapGenerator = require("../lib/source-map-generator").SourceMapGenerator; -const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; +const SourceMapGenerator = + require("../lib/source-map-generator").SourceMapGenerator; +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; const SourceNode = require("../lib/source-node").SourceNode; function forEachNewline(fn) { - return async function(assert) { + return async function (assert) { await fn(assert, "\n"); await fn(assert, "\r\n"); }; } -exports["test .add()"] = function(assert) { +exports["test .add()"] = function (assert) { const node = new SourceNode(null, null, null); // Adding a string works. @@ -27,21 +29,22 @@ exports["test .add()"] = function(assert) { node.add(new SourceNode(null, null, null)); // Adding an array works. - node.add(["function foo() {", - new SourceNode(null, null, null, - "return 10;"), - "}"]); + node.add([ + "function foo() {", + new SourceNode(null, null, null, "return 10;"), + "}", + ]); // Adding other stuff doesn't. - assert.throws(function() { + assert.throws(function () { node.add({}); }, /TypeError: Expected a SourceNode, string, or an array of SourceNodes and strings/); - assert.throws(function() { - node.add(function() {}); + assert.throws(function () { + node.add(function () {}); }, /TypeError: Expected a SourceNode, string, or an array of SourceNodes and strings/); }; -exports["test .prepend()"] = function(assert) { +exports["test .prepend()"] = function (assert) { const node = new SourceNode(null, null, null); // Prepending a string works. @@ -56,10 +59,11 @@ exports["test .prepend()"] = function(assert) { assert.equal(node.children.length, 2); // Prepending an array works. - node.prepend(["function foo() {", - new SourceNode(null, null, null, - "return 10;"), - "}"]); + node.prepend([ + "function foo() {", + new SourceNode(null, null, null, "return 10;"), + "}", + ]); assert.equal(node.children[0], "function foo() {"); assert.equal(node.children[1], "return 10;"); assert.equal(node.children[2], "}"); @@ -68,46 +72,57 @@ exports["test .prepend()"] = function(assert) { assert.equal(node.children.length, 5); // Prepending other stuff doesn't. - assert.throws(function() { + assert.throws(function () { node.prepend({}); }, /TypeError: Expected a SourceNode, string, or an array of SourceNodes and strings/); - assert.throws(function() { - node.prepend(function() {}); + assert.throws(function () { + node.prepend(function () {}); }, /TypeError: Expected a SourceNode, string, or an array of SourceNodes and strings/); }; -exports["test .toString()"] = function(assert) { - assert.equal((new SourceNode(null, null, null, - ["function foo() {", - new SourceNode(null, null, null, "return 10;"), - "}"])).toString(), - "function foo() {return 10;}"); +exports["test .toString()"] = function (assert) { + assert.equal( + new SourceNode(null, null, null, [ + "function foo() {", + new SourceNode(null, null, null, "return 10;"), + "}", + ]).toString(), + "function foo() {return 10;}" + ); }; -exports["test .join()"] = function(assert) { - assert.equal((new SourceNode(null, null, null, - ["a", "b", "c", "d"])).join(", ").toString(), - "a, b, c, d"); +exports["test .join()"] = function (assert) { + assert.equal( + new SourceNode(null, null, null, ["a", "b", "c", "d"]) + .join(", ") + .toString(), + "a, b, c, d" + ); }; -exports["test .walk()"] = function(assert) { - const node = new SourceNode(null, null, null, - ["(function () {\n", - " ", new SourceNode(1, 0, "a.js", ["someCall()"]), ";\n", - " ", new SourceNode(2, 0, "b.js", ["if (foo) bar()"]), ";\n", - "}());"]); +exports["test .walk()"] = function (assert) { + const node = new SourceNode(null, null, null, [ + "(function () {\n", + " ", + new SourceNode(1, 0, "a.js", ["someCall()"]), + ";\n", + " ", + new SourceNode(2, 0, "b.js", ["if (foo) bar()"]), + ";\n", + "}());", + ]); const expected = [ - { str: "(function () {\n", source: null, line: null, column: null }, - { str: " ", source: null, line: null, column: null }, - { str: "someCall()", source: "a.js", line: 1, column: 0 }, - { str: ";\n", source: null, line: null, column: null }, - { str: " ", source: null, line: null, column: null }, - { str: "if (foo) bar()", source: "b.js", line: 2, column: 0 }, - { str: ";\n", source: null, line: null, column: null }, - { str: "}());", source: null, line: null, column: null }, + { str: "(function () {\n", source: null, line: null, column: null }, + { str: " ", source: null, line: null, column: null }, + { str: "someCall()", source: "a.js", line: 1, column: 0 }, + { str: ";\n", source: null, line: null, column: null }, + { str: " ", source: null, line: null, column: null }, + { str: "if (foo) bar()", source: "b.js", line: 2, column: 0 }, + { str: ";\n", source: null, line: null, column: null }, + { str: "}());", source: null, line: null, column: null }, ]; let i = 0; - node.walk(function(chunk, loc) { + node.walk(function (chunk, loc) { assert.equal(expected[i].str, chunk); assert.equal(expected[i].source, loc.source); assert.equal(expected[i].line, loc.line); @@ -116,7 +131,7 @@ exports["test .walk()"] = function(assert) { }); }; -exports["test .replaceRight"] = function(assert) { +exports["test .replaceRight"] = function (assert) { let node; // Not nested @@ -125,38 +140,49 @@ exports["test .replaceRight"] = function(assert) { assert.equal(node.toString(), "hello universe"); // Nested - node = new SourceNode(null, null, null, - [new SourceNode(null, null, null, "hey sexy mama, "), - new SourceNode(null, null, null, "want to kill all humans?")]); + node = new SourceNode(null, null, null, [ + new SourceNode(null, null, null, "hey sexy mama, "), + new SourceNode(null, null, null, "want to kill all humans?"), + ]); node.replaceRight(/kill all humans/, "watch Futurama"); assert.equal(node.toString(), "hey sexy mama, want to watch Futurama?"); }; -exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, nl) { - const node = new SourceNode(null, null, null, - ["(function () {" + nl, - " ", - new SourceNode(1, 0, "a.js", "someCall", "originalCall"), - new SourceNode(1, 8, "a.js", "()"), - ";" + nl, - " ", new SourceNode(2, 0, "b.js", ["if (foo) bar()"]), ";" + nl, - "}());"]); +exports["test .toStringWithSourceMap()"] = forEachNewline(async function ( + assert, + nl +) { + const node = new SourceNode(null, null, null, [ + "(function () {" + nl, + " ", + new SourceNode(1, 0, "a.js", "someCall", "originalCall"), + new SourceNode(1, 8, "a.js", "()"), + ";" + nl, + " ", + new SourceNode(2, 0, "b.js", ["if (foo) bar()"]), + ";" + nl, + "}());", + ]); const result = node.toStringWithSourceMap({ - file: "foo.js" + file: "foo.js", }); - assert.equal(result.code, [ - "(function () {", - " someCall();", - " if (foo) bar();", - "}());" - ].join(nl)); + assert.equal( + result.code, + ["(function () {", " someCall();", " if (foo) bar();", "}());"].join(nl) + ); let map = result.map; const mapWithoutOptions = node.toStringWithSourceMap().map; - assert.ok(map instanceof SourceMapGenerator, "map instanceof SourceMapGenerator"); - assert.ok(mapWithoutOptions instanceof SourceMapGenerator, "mapWithoutOptions instanceof SourceMapGenerator"); + assert.ok( + map instanceof SourceMapGenerator, + "map instanceof SourceMapGenerator" + ); + assert.ok( + mapWithoutOptions instanceof SourceMapGenerator, + "mapWithoutOptions instanceof SourceMapGenerator" + ); assert.ok(!("file" in mapWithoutOptions)); mapWithoutOptions._file = "foo.js"; util.assertEqualMaps(assert, map.toJSON(), mapWithoutOptions.toJSON()); @@ -167,7 +193,7 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, actual = map.originalPositionFor({ line: 1, - column: 4 + column: 4, }); assert.equal(actual.source, null); assert.equal(actual.line, null); @@ -175,7 +201,7 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, actual = map.originalPositionFor({ line: 2, - column: 2 + column: 2, }); assert.equal(actual.source, "a.js"); assert.equal(actual.line, 1); @@ -184,7 +210,7 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, actual = map.originalPositionFor({ line: 3, - column: 2 + column: 2, }); assert.equal(actual.source, "b.js"); assert.equal(actual.line, 2); @@ -192,7 +218,7 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, actual = map.originalPositionFor({ line: 3, - column: 16 + column: 16, }); assert.equal(actual.source, null); assert.equal(actual.line, null); @@ -200,7 +226,7 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, actual = map.originalPositionFor({ line: 4, - column: 2 + column: 2, }); assert.equal(actual.source, null); assert.equal(actual.line, null); @@ -209,85 +235,101 @@ exports["test .toStringWithSourceMap()"] = forEachNewline(async function(assert, map.destroy(); }); -exports["test .fromStringWithSourceMap()"] = forEachNewline(async function(assert, nl) { +exports["test .fromStringWithSourceMap()"] = forEachNewline(async function ( + assert, + nl +) { const testCode = util.testGeneratedCode.replace(/\n/g, nl); let map = await new SourceMapConsumer(util.testMap); - const node = SourceNode.fromStringWithSourceMap( - testCode, - map - ); + const node = SourceNode.fromStringWithSourceMap(testCode, map); map.destroy(); const result = node.toStringWithSourceMap({ - file: "min.js" + file: "min.js", }); map = result.map; const code = result.code; assert.equal(code, testCode); - assert.ok(map instanceof SourceMapGenerator, "map instanceof SourceMapGenerator"); + assert.ok( + map instanceof SourceMapGenerator, + "map instanceof SourceMapGenerator" + ); map = map.toJSON(); assert.equal(map.version, util.testMap.version); assert.equal(map.file, util.testMap.file); assert.equal(map.mappings, util.testMap.mappings); }); -exports["test .fromStringWithSourceMap() empty map"] = forEachNewline(async function(assert, nl) { - let map = await new SourceMapConsumer(util.emptyMap); - const node = SourceNode.fromStringWithSourceMap( - util.testGeneratedCode.replace(/\n/g, nl), - map - ); - map.destroy(); - - const result = node.toStringWithSourceMap({ - file: "min.js" - }); - map = result.map; - const code = result.code; - - assert.equal(code, util.testGeneratedCode.replace(/\n/g, nl)); - assert.ok(map instanceof SourceMapGenerator, "map instanceof SourceMapGenerator"); - map = map.toJSON(); - assert.equal(map.version, util.emptyMap.version); - assert.equal(map.file, util.emptyMap.file); - assert.equal(map.mappings.length, util.emptyMap.mappings.length); - assert.equal(map.mappings, util.emptyMap.mappings); -}); +exports["test .fromStringWithSourceMap() empty map"] = forEachNewline( + async function (assert, nl) { + let map = await new SourceMapConsumer(util.emptyMap); + const node = SourceNode.fromStringWithSourceMap( + util.testGeneratedCode.replace(/\n/g, nl), + map + ); + map.destroy(); -exports["test .fromStringWithSourceMap() complex version"] = forEachNewline(async function(assert, nl) { - let input = new SourceNode(null, null, null, [ - "(function() {" + nl, + const result = node.toStringWithSourceMap({ + file: "min.js", + }); + map = result.map; + const code = result.code; + + assert.equal(code, util.testGeneratedCode.replace(/\n/g, nl)); + assert.ok( + map instanceof SourceMapGenerator, + "map instanceof SourceMapGenerator" + ); + map = map.toJSON(); + assert.equal(map.version, util.emptyMap.version); + assert.equal(map.file, util.emptyMap.file); + assert.equal(map.mappings.length, util.emptyMap.mappings.length); + assert.equal(map.mappings, util.emptyMap.mappings); + } +); + +exports["test .fromStringWithSourceMap() complex version"] = forEachNewline( + async function (assert, nl) { + let input = new SourceNode(null, null, null, [ + "(function() {" + nl, " var Test = {};" + nl, - " ", new SourceNode(1, 0, "a.js", "Test.A = { value: 1234 };" + nl), - " ", new SourceNode(2, 0, "a.js", "Test.A.x = 'xyz';"), nl, + " ", + new SourceNode(1, 0, "a.js", "Test.A = { value: 1234 };" + nl), + " ", + new SourceNode(2, 0, "a.js", "Test.A.x = 'xyz';"), + nl, "}());" + nl, - "/* Generated Source */"]); - input = input.toStringWithSourceMap({ - file: "foo.js" - }); - - let map = await new SourceMapConsumer(input.map.toString()); - const node = SourceNode.fromStringWithSourceMap( - input.code, - map - ); - map.destroy(); - - const result = node.toStringWithSourceMap({ - file: "foo.js" - }); - map = result.map; - const code = result.code; + "/* Generated Source */", + ]); + input = input.toStringWithSourceMap({ + file: "foo.js", + }); - assert.equal(code, input.code); - assert.ok(map instanceof SourceMapGenerator, "map instanceof SourceMapGenerator"); - map = map.toJSON(); - const inputMap = input.map.toJSON(); - util.assertEqualMaps(assert, map, inputMap); -}); + let map = await new SourceMapConsumer(input.map.toString()); + const node = SourceNode.fromStringWithSourceMap(input.code, map); + map.destroy(); -exports["test .fromStringWithSourceMap() third argument"] = async function(assert) { + const result = node.toStringWithSourceMap({ + file: "foo.js", + }); + map = result.map; + const code = result.code; + + assert.equal(code, input.code); + assert.ok( + map instanceof SourceMapGenerator, + "map instanceof SourceMapGenerator" + ); + map = map.toJSON(); + const inputMap = input.map.toJSON(); + util.assertEqualMaps(assert, map, inputMap); + } +); + +exports["test .fromStringWithSourceMap() third argument"] = async function ( + assert +) { // Assume the following directory structure: // // http://foo.org/ @@ -307,278 +349,278 @@ exports["test .fromStringWithSourceMap() third argument"] = async function(asser coffeeBundle.setSourceContent("foo.coffee", "foo coffee"); coffeeBundle = coffeeBundle.toStringWithSourceMap({ file: "foo.js", - sourceRoot: ".." + sourceRoot: "..", }); const foo = new SourceNode(1, 0, "foo.js", "foo(js);"); - const test = async function(relativePath, expectedSources) { + const test = async function (relativePath, expectedSources) { const app = new SourceNode(); const map = await new SourceMapConsumer(coffeeBundle.map.toString()); - app.add(SourceNode.fromStringWithSourceMap( - coffeeBundle.code, - map, - relativePath - )); + app.add( + SourceNode.fromStringWithSourceMap(coffeeBundle.code, map, relativePath) + ); map.destroy(); app.add(foo); let i = 0; - app.walk(function(chunk, loc) { + app.walk(function (chunk, loc) { assert.equal(loc.source, expectedSources[i]); i++; }); - app.walkSourceContents(function(sourceFile, sourceContent) { + app.walkSourceContents(function (sourceFile, sourceContent) { assert.equal(sourceFile, expectedSources[0]); assert.equal(sourceContent, "foo coffee"); }); }; - await test("../coffee/maps", [ - "../coffee/foo.coffee", - "foo.js" - ]); + await test("../coffee/maps", ["../coffee/foo.coffee", "foo.js"]); // If the third parameter is omitted or set to the current working // directory we get incorrect source paths: - await test(undefined, [ - "../foo.coffee", - "foo.js" - ]); + await test(undefined, ["../foo.coffee", "foo.js"]); - await test("", [ - "../foo.coffee", - "foo.js" - ]); + await test("", ["../foo.coffee", "foo.js"]); - await test(".", [ - "../foo.coffee", - "foo.js" - ]); + await test(".", ["../foo.coffee", "foo.js"]); - await test("./", [ - "../foo.coffee", - "foo.js" - ]); + await test("./", ["../foo.coffee", "foo.js"]); }; -exports["test .toStringWithSourceMap() merging duplicate mappings"] = forEachNewline(function(assert, nl) { - let input = new SourceNode(null, null, null, [ - new SourceNode(1, 0, "a.js", "(function"), - new SourceNode(1, 0, "a.js", "() {" + nl), - " ", - new SourceNode(1, 0, "a.js", "var Test = "), - new SourceNode(1, 0, "b.js", "{};" + nl), - new SourceNode(2, 0, "b.js", "Test"), - new SourceNode(2, 0, "b.js", ".A", "A"), - new SourceNode(2, 20, "b.js", " = { value: ", "A"), - "1234", - new SourceNode(2, 40, "b.js", " };" + nl, "A"), - "}());" + nl, - "/* Generated Source */" - ]); - input = input.toStringWithSourceMap({ - file: "foo.js" - }); - - assert.equal(input.code, [ - "(function() {", - " var Test = {};", - "Test.A = { value: 1234 };", - "}());", - "/* Generated Source */" - ].join(nl)); - - let correctMap = new SourceMapGenerator({ - file: "foo.js" - }); - correctMap.addMapping({ - generated: { line: 1, column: 0 }, - source: "a.js", - original: { line: 1, column: 0 } - }); - // Here is no need for a empty mapping, - // because mappings ends at eol - correctMap.addMapping({ - generated: { line: 2, column: 2 }, - source: "a.js", - original: { line: 1, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 2, column: 13 }, - source: "b.js", - original: { line: 1, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 3, column: 0 }, - source: "b.js", - original: { line: 2, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 3, column: 4 }, - source: "b.js", - name: "A", - original: { line: 2, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 3, column: 6 }, - source: "b.js", - name: "A", - original: { line: 2, column: 20 } - }); - // This empty mapping is required, - // because there is a hole in the middle of the line - correctMap.addMapping({ - generated: { line: 3, column: 18 } - }); - correctMap.addMapping({ - generated: { line: 3, column: 22 }, - source: "b.js", - name: "A", - original: { line: 2, column: 40 } - }); - // Here is no need for a empty mapping, - // because mappings ends at eol +exports["test .toStringWithSourceMap() merging duplicate mappings"] = + forEachNewline(function (assert, nl) { + let input = new SourceNode(null, null, null, [ + new SourceNode(1, 0, "a.js", "(function"), + new SourceNode(1, 0, "a.js", "() {" + nl), + " ", + new SourceNode(1, 0, "a.js", "var Test = "), + new SourceNode(1, 0, "b.js", "{};" + nl), + new SourceNode(2, 0, "b.js", "Test"), + new SourceNode(2, 0, "b.js", ".A", "A"), + new SourceNode(2, 20, "b.js", " = { value: ", "A"), + "1234", + new SourceNode(2, 40, "b.js", " };" + nl, "A"), + "}());" + nl, + "/* Generated Source */", + ]); + input = input.toStringWithSourceMap({ + file: "foo.js", + }); - const inputMap = input.map.toJSON(); - correctMap = correctMap.toJSON(); - util.assertEqualMaps(assert, inputMap, correctMap); -}); + assert.equal( + input.code, + [ + "(function() {", + " var Test = {};", + "Test.A = { value: 1234 };", + "}());", + "/* Generated Source */", + ].join(nl) + ); + + let correctMap = new SourceMapGenerator({ + file: "foo.js", + }); + correctMap.addMapping({ + generated: { line: 1, column: 0 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + // Here is no need for a empty mapping, + // because mappings ends at eol + correctMap.addMapping({ + generated: { line: 2, column: 2 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 2, column: 13 }, + source: "b.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 3, column: 0 }, + source: "b.js", + original: { line: 2, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 3, column: 4 }, + source: "b.js", + name: "A", + original: { line: 2, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 3, column: 6 }, + source: "b.js", + name: "A", + original: { line: 2, column: 20 }, + }); + // This empty mapping is required, + // because there is a hole in the middle of the line + correctMap.addMapping({ + generated: { line: 3, column: 18 }, + }); + correctMap.addMapping({ + generated: { line: 3, column: 22 }, + source: "b.js", + name: "A", + original: { line: 2, column: 40 }, + }); + // Here is no need for a empty mapping, + // because mappings ends at eol + + const inputMap = input.map.toJSON(); + correctMap = correctMap.toJSON(); + util.assertEqualMaps(assert, inputMap, correctMap); + }); + +exports["test .toStringWithSourceMap() multi-line SourceNodes"] = + forEachNewline(function (assert, nl) { + let input = new SourceNode(null, null, null, [ + new SourceNode( + 1, + 0, + "a.js", + "(function() {" + nl + "var nextLine = 1;" + nl + "anotherLine();" + nl + ), + new SourceNode(2, 2, "b.js", "Test.call(this, 123);" + nl), + new SourceNode(2, 2, "b.js", "this['stuff'] = 'v';" + nl), + new SourceNode(2, 2, "b.js", "anotherLine();" + nl), + "/*" + nl + "Generated" + nl + "Source" + nl + "*/" + nl, + new SourceNode(3, 4, "c.js", "anotherLine();" + nl), + "/*" + nl + "Generated" + nl + "Source" + nl + "*/", + ]); + input = input.toStringWithSourceMap({ + file: "foo.js", + }); -exports["test .toStringWithSourceMap() multi-line SourceNodes"] = forEachNewline(function(assert, nl) { - let input = new SourceNode(null, null, null, [ - new SourceNode(1, 0, "a.js", "(function() {" + nl + "var nextLine = 1;" + nl + "anotherLine();" + nl), - new SourceNode(2, 2, "b.js", "Test.call(this, 123);" + nl), - new SourceNode(2, 2, "b.js", "this['stuff'] = 'v';" + nl), - new SourceNode(2, 2, "b.js", "anotherLine();" + nl), - "/*" + nl + "Generated" + nl + "Source" + nl + "*/" + nl, - new SourceNode(3, 4, "c.js", "anotherLine();" + nl), - "/*" + nl + "Generated" + nl + "Source" + nl + "*/" - ]); - input = input.toStringWithSourceMap({ - file: "foo.js" - }); + assert.equal( + input.code, + [ + "(function() {", + "var nextLine = 1;", + "anotherLine();", + "Test.call(this, 123);", + "this['stuff'] = 'v';", + "anotherLine();", + "/*", + "Generated", + "Source", + "*/", + "anotherLine();", + "/*", + "Generated", + "Source", + "*/", + ].join(nl) + ); + + let correctMap = new SourceMapGenerator({ + file: "foo.js", + }); + correctMap.addMapping({ + generated: { line: 1, column: 0 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 2, column: 0 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 3, column: 0 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 4, column: 0 }, + source: "b.js", + original: { line: 2, column: 2 }, + }); + correctMap.addMapping({ + generated: { line: 5, column: 0 }, + source: "b.js", + original: { line: 2, column: 2 }, + }); + correctMap.addMapping({ + generated: { line: 6, column: 0 }, + source: "b.js", + original: { line: 2, column: 2 }, + }); + correctMap.addMapping({ + generated: { line: 11, column: 0 }, + source: "c.js", + original: { line: 3, column: 4 }, + }); - assert.equal(input.code, [ - "(function() {", - "var nextLine = 1;", - "anotherLine();", - "Test.call(this, 123);", - "this['stuff'] = 'v';", - "anotherLine();", - "/*", - "Generated", - "Source", - "*/", - "anotherLine();", - "/*", - "Generated", - "Source", - "*/" - ].join(nl)); - - let correctMap = new SourceMapGenerator({ - file: "foo.js" - }); - correctMap.addMapping({ - generated: { line: 1, column: 0 }, - source: "a.js", - original: { line: 1, column: 0 } + const inputMap = input.map.toJSON(); + correctMap = correctMap.toJSON(); + util.assertEqualMaps(assert, inputMap, correctMap); }); - correctMap.addMapping({ - generated: { line: 2, column: 0 }, - source: "a.js", - original: { line: 1, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 3, column: 0 }, - source: "a.js", - original: { line: 1, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 4, column: 0 }, - source: "b.js", - original: { line: 2, column: 2 } - }); - correctMap.addMapping({ - generated: { line: 5, column: 0 }, - source: "b.js", - original: { line: 2, column: 2 } - }); - correctMap.addMapping({ - generated: { line: 6, column: 0 }, - source: "b.js", - original: { line: 2, column: 2 } - }); - correctMap.addMapping({ - generated: { line: 11, column: 0 }, - source: "c.js", - original: { line: 3, column: 4 } - }); - - const inputMap = input.map.toJSON(); - correctMap = correctMap.toJSON(); - util.assertEqualMaps(assert, inputMap, correctMap); -}); -exports["test .toStringWithSourceMap() with empty string"] = function(assert) { +exports["test .toStringWithSourceMap() with empty string"] = function (assert) { const node = new SourceNode(1, 0, "empty.js", ""); const result = node.toStringWithSourceMap(); assert.equal(result.code, ""); }; -exports["test .toStringWithSourceMap() with consecutive newlines"] = forEachNewline(function(assert, nl) { - let input = new SourceNode(null, null, null, [ - "/***/" + nl + nl, - new SourceNode(1, 0, "a.js", "'use strict';" + nl), - new SourceNode(2, 0, "a.js", "a();"), - ]); - input = input.toStringWithSourceMap({ - file: "foo.js" - }); +exports["test .toStringWithSourceMap() with consecutive newlines"] = + forEachNewline(function (assert, nl) { + let input = new SourceNode(null, null, null, [ + "/***/" + nl + nl, + new SourceNode(1, 0, "a.js", "'use strict';" + nl), + new SourceNode(2, 0, "a.js", "a();"), + ]); + input = input.toStringWithSourceMap({ + file: "foo.js", + }); - assert.equal(input.code, [ - "/***/", - "", - "'use strict';", - "a();", - ].join(nl)); + assert.equal(input.code, ["/***/", "", "'use strict';", "a();"].join(nl)); - let correctMap = new SourceMapGenerator({ - file: "foo.js" - }); - correctMap.addMapping({ - generated: { line: 3, column: 0 }, - source: "a.js", - original: { line: 1, column: 0 } - }); - correctMap.addMapping({ - generated: { line: 4, column: 0 }, - source: "a.js", - original: { line: 2, column: 0 } - }); + let correctMap = new SourceMapGenerator({ + file: "foo.js", + }); + correctMap.addMapping({ + generated: { line: 3, column: 0 }, + source: "a.js", + original: { line: 1, column: 0 }, + }); + correctMap.addMapping({ + generated: { line: 4, column: 0 }, + source: "a.js", + original: { line: 2, column: 0 }, + }); - const inputMap = input.map.toJSON(); - correctMap = correctMap.toJSON(); - util.assertEqualMaps(assert, inputMap, correctMap); -}); + const inputMap = input.map.toJSON(); + correctMap = correctMap.toJSON(); + util.assertEqualMaps(assert, inputMap, correctMap); + }); -exports["test setSourceContent with toStringWithSourceMap"] = async function(assert) { +exports["test setSourceContent with toStringWithSourceMap"] = async function ( + assert +) { const aNode = new SourceNode(1, 1, "a.js", "a"); aNode.setSourceContent("a.js", "someContent"); - const node = new SourceNode(null, null, null, - ["(function () {\n", - " ", aNode, - " ", new SourceNode(1, 1, "b.js", "b"), - "}());"]); + const node = new SourceNode(null, null, null, [ + "(function () {\n", + " ", + aNode, + " ", + new SourceNode(1, 1, "b.js", "b"), + "}());", + ]); node.setSourceContent("b.js", "otherContent"); let map = node.toStringWithSourceMap({ - file: "foo.js" + file: "foo.js", }).map; - assert.ok(map instanceof SourceMapGenerator, "map instanceof SourceMapGenerator"); + assert.ok( + map instanceof SourceMapGenerator, + "map instanceof SourceMapGenerator" + ); map = await new SourceMapConsumer(map.toString()); assert.equal(map.sources.length, 2); @@ -591,17 +633,20 @@ exports["test setSourceContent with toStringWithSourceMap"] = async function(ass map.destroy(); }; -exports["test walkSourceContents"] = function(assert) { +exports["test walkSourceContents"] = function (assert) { const aNode = new SourceNode(1, 1, "a.js", "a"); aNode.setSourceContent("a.js", "someContent"); - const node = new SourceNode(null, null, null, - ["(function () {\n", - " ", aNode, - " ", new SourceNode(1, 1, "b.js", "b"), - "}());"]); + const node = new SourceNode(null, null, null, [ + "(function () {\n", + " ", + aNode, + " ", + new SourceNode(1, 1, "b.js", "b"), + "}());", + ]); node.setSourceContent("b.js", "otherContent"); const results = []; - node.walkSourceContents(function(sourceFile, sourceContent) { + node.walkSourceContents(function (sourceFile, sourceContent) { results.push([sourceFile, sourceContent]); }); assert.equal(results.length, 2); @@ -611,19 +656,17 @@ exports["test walkSourceContents"] = function(assert) { assert.equal(results[1][1], "otherContent"); }; -exports["test from issue 258"] = async function(assert) { +exports["test from issue 258"] = async function (assert) { const node = new SourceNode(); const reactCode = - ";require(0);\n//# sourceMappingURL=/index.ios.map?platform=ios&dev=false&minify=true"; + ";require(0);\n//# sourceMappingURL=/index.ios.map?platform=ios&dev=false&minify=true"; const reactMap = - '{"version":3,"file":"/index.ios.bundle?platform=ios&dev=false&minify=true","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"sources":["require-0.js"],"names":[],"mappings":"AAAA;","file":"require-0.js","sourcesContent":[";require(0);"]}}]}'; + // eslint-disable-next-line + '{"version":3,"file":"/index.ios.bundle?platform=ios&dev=false&minify=true","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"sources":["require-0.js"],"names":[],"mappings":"AAAA;","file":"require-0.js","sourcesContent":[";require(0);"]}}]}'; const map = await new SourceMapConsumer(reactMap); - node.add(SourceNode.fromStringWithSourceMap( - reactCode, - map - )); + node.add(SourceNode.fromStringWithSourceMap(reactCode, map)); map.destroy(); }; diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js new file mode 100644 index 00000000..8f113160 --- /dev/null +++ b/test/test-spec-tests.js @@ -0,0 +1,208 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2024 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +const fs = require("fs").promises; +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; + +const sourceMapSpecTests = require("./source-map-tests/source-map-spec-tests.json"); + +async function readJSON(path) { + const file = await fs.open(require.resolve(path)); + const json = JSON.parse(await file.readFile()); + file.close(); + return json; +} + +// Known failures due to intentional implementation choices or due to bugs. +const skippedTests = [ + // Versions are explicitly checked a bit loosely. + "versionNumericString", + // Stricter sources array checking isn't implemented. + "sourcesNotStringOrNull", + "sourcesAndSourcesContentBothNull", + // Stricter names array checking isn't implemented. + "namesMissing", + "namesNotString", + // This check isn't as strict in this library. + "invalidMappingNotAString1", + // A mapping segment with no fields is technically invalid in the spec. + "invalidMappingSegmentWithZeroFields", + // These tests fail due to imprecision in the spec about the 32-bit limit. + "invalidMappingSegmentWithColumnExceeding32Bits", + "invalidMappingSegmentWithOriginalLineExceeding32Bits", + "invalidMappingSegmentWithOriginalColumnExceeding32Bits", + // A large VLQ that should parse, but currently does not. + "validMappingLargeVLQ", + // The library currently doesn't check the types of offset lines/columns. + "indexMapOffsetLineWrongType", + "indexMapOffsetColumnWrongType", + // The spec is not totally clear about this case. + "indexMapInvalidBaseMappings", + // The spec's definition of overlap can be refined + "indexMapInvalidOverlap", + // The library doesn't support the new ignoreList feature yet. + "ignoreListWrongType1", + "ignoreListWrongType2", + "ignoreListWrongType3", + "ignoreListOutOfBounds", +]; + +// The source-map library converts null sources to the "null" URL in its +// sources list, so for equality checking we accept this as null. +function nullish(nullOrString) { + if (nullOrString === "null") { + return null; + } + return nullOrString; +} + +function mapLine(line) { + return line + 1; +} + +async function testMappingAction(assert, rawSourceMap, action) { + return SourceMapConsumer.with(rawSourceMap, null, consumer => { + let mappedPosition = consumer.originalPositionFor({ + line: mapLine(action.generatedLine), + column: action.generatedColumn, + }); + + assert.equal( + mappedPosition.line, + mapLine(action.originalLine), + `original line didn't match, expected ${mapLine( + action.originalLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.originalColumn, + `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` + ); + assert.equal( + nullish(mappedPosition.source), + action.originalSource, + `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` + ); + if (action.mappedName) { + assert.equal( + mappedPosition.name, + action.mappedName, + `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}` + ); + } + + // When the source is null, a reverse lookup may not make sense + // because there isn't a unique way to look it up. + if (action.originalSource !== null) { + mappedPosition = consumer.generatedPositionFor({ + source: action.originalSource, + line: mapLine(action.originalLine), + column: action.originalColumn, + }); + + assert.equal( + mappedPosition.line, + mapLine(action.generatedLine), + `generated line didn't match, expected ${mapLine( + action.generatedLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.generatedColumn, + `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}` + ); + } + }); +} + +async function testTransitiveMappingAction(assert, rawSourceMap, action) { + return SourceMapConsumer.with(rawSourceMap, null, async consumer => { + assert.ok( + Array.isArray(action.intermediateMaps), + "transitive mapping case requires intermediate maps" + ); + + let mappedPosition = consumer.originalPositionFor({ + line: mapLine(action.generatedLine), + column: action.generatedColumn, + }); + + for (const intermediateMapPath of action.intermediateMaps) { + const intermediateMap = await readJSON( + `./source-map-tests/resources/${intermediateMapPath}` + ); + await SourceMapConsumer.with( + intermediateMap, + null, + consumerIntermediate => { + mappedPosition = consumerIntermediate.originalPositionFor({ + line: mappedPosition.line, + column: mappedPosition.column, + }); + } + ); + } + + assert.equal( + mappedPosition.line, + mapLine(action.originalLine), + `original line didn't match, expected ${mapLine( + action.originalLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.originalColumn, + `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` + ); + assert.equal( + mappedPosition.source, + action.originalSource, + `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` + ); + }); +} + +for (const testCase of sourceMapSpecTests.tests) { + if (skippedTests.includes(testCase.name)) { + continue; + } + exports[`test from source map spec tests, name: ${testCase.name}`] = + async function (assert) { + const json = await readJSON( + `./source-map-tests/resources/${testCase.sourceMapFile}` + ); + try { + const map = await new SourceMapConsumer(json); + map.eachMapping(() => {}); + map.destroy(); + } catch (exn) { + if (testCase.sourceMapIsValid) { + assert.fail( + "Expected valid source map but failed to load successfully: " + + exn.message + ); + } + return; + } + if (!testCase.sourceMapIsValid) { + assert.fail("Expected invalid source map but loaded successfully"); + } + if (testCase.testActions) { + for (const testAction of testCase.testActions) { + if (testAction.actionType == "checkMapping") { + await testMappingAction(assert, json, testAction); + } else if (testAction.actionType == "checkMappingTransitive") { + await testTransitiveMappingAction(assert, json, testAction); + } + } + } + }; +} diff --git a/test/test-util.js b/test/test-util.js index e665847c..e25b737e 100644 --- a/test/test-util.js +++ b/test/test-util.js @@ -6,58 +6,19 @@ */ const libUtil = require("../lib/util"); - -exports["test urls"] = function(assert) { - const assertUrl = function(url) { - assert.equal(url, libUtil.urlGenerate(libUtil.urlParse(url))); - }; - assertUrl("http://"); - assertUrl("http://www.example.com/"); - assertUrl("http://user:pass@www.example.com/"); - assertUrl("http://www.example.com/"); - assertUrl("http://www.example.com/"); - assertUrl("http://www.example.com/foo/bar"); - assertUrl("http://www.example.com/foo/bar/"); - assertUrl("http://user:pass@www.example.com/foo/bar/"); - - assertUrl("//"); - assertUrl("//www.example.com"); - assertUrl("file:///www.example.com"); - - assert.equal(libUtil.urlParse(""), null); - assert.equal(libUtil.urlParse("."), null); - assert.equal(libUtil.urlParse(".."), null); - assert.equal(libUtil.urlParse("a"), null); - assert.equal(libUtil.urlParse("a/b"), null); - assert.equal(libUtil.urlParse("a//b"), null); - assert.equal(libUtil.urlParse("/a"), null); - assert.equal(libUtil.urlParse("data:foo,bar"), null); - - let parsed = libUtil.urlParse("http://x-y.com/bar"); - assert.equal(parsed.scheme, "http"); - assert.equal(parsed.host, "x-y.com"); - assert.equal(parsed.path, "/bar"); - - const webpackURL = "webpack:///webpack/bootstrap 67e184f9679733298d44"; - parsed = libUtil.urlParse(webpackURL); - assert.equal(parsed.scheme, "webpack"); - assert.equal(parsed.host, ""); - assert.equal(parsed.path, "/webpack/bootstrap 67e184f9679733298d44"); - assert.equal(webpackURL, libUtil.urlGenerate(parsed)); -}; - -exports["test normalize()"] = function(assert) { +exports["test normalize()"] = function (assert) { assert.equal(libUtil.normalize("/.."), "/"); assert.equal(libUtil.normalize("/../"), "/"); assert.equal(libUtil.normalize("/../../../.."), "/"); assert.equal(libUtil.normalize("/../../../../a/b/c"), "/a/b/c"); assert.equal(libUtil.normalize("/a/b/c/../../../d/../../e"), "/e"); - assert.equal(libUtil.normalize(".."), ".."); + assert.equal(libUtil.normalize(".."), "../"); assert.equal(libUtil.normalize("../"), "../"); + assert.equal(libUtil.normalize("../../a/"), "../../a/"); - assert.equal(libUtil.normalize("a/.."), "."); - assert.equal(libUtil.normalize("a/../../.."), "../.."); + assert.equal(libUtil.normalize("a/.."), ""); + assert.equal(libUtil.normalize("a/../../.."), "../../"); assert.equal(libUtil.normalize("/."), "/"); assert.equal(libUtil.normalize("/./"), "/"); @@ -65,156 +26,201 @@ exports["test normalize()"] = function(assert) { assert.equal(libUtil.normalize("/././././a/b/c"), "/a/b/c"); assert.equal(libUtil.normalize("/a/b/c/./././d/././e"), "/a/b/c/d/e"); - assert.equal(libUtil.normalize(""), "."); - assert.equal(libUtil.normalize("."), "."); - assert.equal(libUtil.normalize("./"), "."); + assert.equal(libUtil.normalize(""), ""); + assert.equal(libUtil.normalize("."), ""); + assert.equal(libUtil.normalize("./"), ""); assert.equal(libUtil.normalize("././a"), "a"); assert.equal(libUtil.normalize("a/./"), "a/"); - assert.equal(libUtil.normalize("a/././."), "a"); - - assert.equal(libUtil.normalize("/a/b//c////d/////"), "/a/b/c/d/"); - assert.equal(libUtil.normalize("///a/b//c////d/////"), "///a/b/c/d/"); - assert.equal(libUtil.normalize("a/b//c////d"), "a/b/c/d"); - - assert.equal(libUtil.normalize(".///.././../a/b//./.."), "../../a"); - - assert.equal(libUtil.normalize("http://www.example.com/"), "http://www.example.com/"); - assert.equal(libUtil.normalize("http://www.example.com/"), "http://www.example.com/"); - assert.equal(libUtil.normalize("http://www.example.com//a/b/d//"), "http://www.example.com/a/b/d/"); + assert.equal(libUtil.normalize("a/././."), "a/"); + + assert.equal(libUtil.normalize("/a/b//c////d/////"), "/a/b//c////d/////"); + + assert.equal(libUtil.normalize("///a/b//c////d/////"), "//a/b//c////d/////"); + assert.equal(libUtil.normalize("a/b//c////d"), "a/b//c////d"); + + assert.equal(libUtil.normalize(".///.././../a/b//./.."), "a/b/"); + + assert.equal( + libUtil.normalize("http://www.example.com/"), + "http://www.example.com/" + ); + assert.equal( + libUtil.normalize("http://www.example.com/"), + "http://www.example.com/" + ); + assert.equal( + libUtil.normalize("http://www.example.com//a/b/d//"), + "http://www.example.com//a/b/d//" + ); }; -exports["test join()"] = function(assert) { +exports["test join()"] = function (assert) { assert.equal(libUtil.join("a", "b"), "a/b"); assert.equal(libUtil.join("a/", "b"), "a/b"); - assert.equal(libUtil.join("a//", "b"), "a/b"); + assert.equal(libUtil.join("a//", "b"), "a//b"); assert.equal(libUtil.join("a", "b/"), "a/b/"); - assert.equal(libUtil.join("a", "b//"), "a/b/"); + assert.equal(libUtil.join("a", "b//"), "a/b//"); assert.equal(libUtil.join("a/", "/b"), "/b"); - assert.equal(libUtil.join("a//", "//b"), "//b"); + assert.equal(libUtil.join("a//", "//b"), "//b/"); - assert.equal(libUtil.join("a", ".."), "."); + assert.equal(libUtil.join("a", ".."), ""); assert.equal(libUtil.join("a", "../b"), "b"); assert.equal(libUtil.join("a/b", "../c"), "a/c"); - assert.equal(libUtil.join("a", "."), "a"); + assert.equal(libUtil.join("a", "."), "a/"); assert.equal(libUtil.join("a", "./b"), "a/b"); assert.equal(libUtil.join("a/b", "./c"), "a/b/c"); - assert.equal(libUtil.join("a", "http://www.example.com/"), "http://www.example.com/"); + assert.equal( + libUtil.join("a", "http://www.example.com/"), + "http://www.example.com/" + ); assert.equal(libUtil.join("a", "data:foo,bar"), "data:foo,bar"); - assert.equal(libUtil.join("", "b"), "b"); assert.equal(libUtil.join(".", "b"), "b"); assert.equal(libUtil.join("", "b/"), "b/"); assert.equal(libUtil.join(".", "b/"), "b/"); - assert.equal(libUtil.join("", "b//"), "b/"); - assert.equal(libUtil.join(".", "b//"), "b/"); + assert.equal(libUtil.join("", "b//"), "b//"); + assert.equal(libUtil.join(".", "b//"), "b//"); - assert.equal(libUtil.join("", ".."), ".."); - assert.equal(libUtil.join(".", ".."), ".."); + assert.equal(libUtil.join("", ".."), "../"); + assert.equal(libUtil.join(".", ".."), "../"); assert.equal(libUtil.join("", "../b"), "../b"); assert.equal(libUtil.join(".", "../b"), "../b"); - assert.equal(libUtil.join("", "."), "."); - assert.equal(libUtil.join(".", "."), "."); + assert.equal(libUtil.join("", "."), ""); + assert.equal(libUtil.join(".", "."), ""); assert.equal(libUtil.join("", "./b"), "b"); assert.equal(libUtil.join(".", "./b"), "b"); - assert.equal(libUtil.join("", "http://www.example.com/"), "http://www.example.com/"); - assert.equal(libUtil.join(".", "http://www.example.com/"), "http://www.example.com/"); + assert.equal( + libUtil.join("", "http://www.example.com/"), + "http://www.example.com/" + ); + assert.equal( + libUtil.join(".", "http://www.example.com/"), + "http://www.example.com/" + ); assert.equal(libUtil.join("", "data:foo,bar"), "data:foo,bar"); assert.equal(libUtil.join(".", "data:foo,bar"), "data:foo,bar"); - assert.equal(libUtil.join("..", "b"), "../b"); assert.equal(libUtil.join("..", "b/"), "../b/"); - assert.equal(libUtil.join("..", "b//"), "../b/"); + assert.equal(libUtil.join("..", "b//"), "../b//"); - assert.equal(libUtil.join("..", ".."), "../.."); + assert.equal(libUtil.join("..", ".."), "../../"); assert.equal(libUtil.join("..", "../b"), "../../b"); - assert.equal(libUtil.join("..", "."), ".."); + assert.equal(libUtil.join("..", "."), "../"); assert.equal(libUtil.join("..", "./b"), "../b"); - assert.equal(libUtil.join("..", "http://www.example.com/"), "http://www.example.com/"); + assert.equal( + libUtil.join("..", "http://www.example.com/"), + "http://www.example.com/" + ); assert.equal(libUtil.join("..", "data:foo,bar"), "data:foo,bar"); - - assert.equal(libUtil.join("a", ""), "a"); - assert.equal(libUtil.join("a", "."), "a"); - assert.equal(libUtil.join("a/", ""), "a"); - assert.equal(libUtil.join("a/", "."), "a"); - assert.equal(libUtil.join("a//", ""), "a"); - assert.equal(libUtil.join("a//", "."), "a"); - assert.equal(libUtil.join("/a", ""), "/a"); - assert.equal(libUtil.join("/a", "."), "/a"); - assert.equal(libUtil.join("", ""), "."); - assert.equal(libUtil.join(".", ""), "."); - assert.equal(libUtil.join(".", ""), "."); - assert.equal(libUtil.join(".", "."), "."); - assert.equal(libUtil.join("..", ""), ".."); - assert.equal(libUtil.join("..", "."), ".."); - assert.equal(libUtil.join("http://foo.org/a", ""), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org/a", "."), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org/a/", ""), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org/a/", "."), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org/a//", ""), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org/a//", "."), "http://foo.org/a"); + assert.equal(libUtil.join("a", ""), "a/"); + assert.equal(libUtil.join("a", "."), "a/"); + assert.equal(libUtil.join("a/", ""), "a/"); + assert.equal(libUtil.join("a/", "."), "a/"); + assert.equal(libUtil.join("a//", ""), "a//"); + assert.equal(libUtil.join("a//", "."), "a//"); + assert.equal(libUtil.join("/a", ""), "/a/"); + assert.equal(libUtil.join("/a", "."), "/a/"); + assert.equal(libUtil.join("", ""), ""); + assert.equal(libUtil.join(".", ""), ""); + assert.equal(libUtil.join(".", ""), ""); + assert.equal(libUtil.join(".", "."), ""); + assert.equal(libUtil.join("..", ""), "../"); + assert.equal(libUtil.join("..", "."), "../"); + assert.equal(libUtil.join("http://foo.org/a", ""), "http://foo.org/a/"); + assert.equal(libUtil.join("http://foo.org/a", "."), "http://foo.org/a/"); + assert.equal(libUtil.join("http://foo.org/a/", ""), "http://foo.org/a/"); + assert.equal(libUtil.join("http://foo.org/a/", "."), "http://foo.org/a/"); + assert.equal(libUtil.join("http://foo.org/a//", ""), "http://foo.org/a//"); + assert.equal(libUtil.join("http://foo.org/a//", "."), "http://foo.org/a//"); assert.equal(libUtil.join("http://foo.org/", ""), "http://foo.org/"); assert.equal(libUtil.join("http://foo.org/", "."), "http://foo.org/"); assert.equal(libUtil.join("http://foo.org/", ""), "http://foo.org/"); assert.equal(libUtil.join("http://foo.org/", "."), "http://foo.org/"); - assert.equal(libUtil.join("http://foo.org//", ""), "http://foo.org/"); - assert.equal(libUtil.join("http://foo.org//", "."), "http://foo.org/"); + assert.equal(libUtil.join("http://foo.org//", ""), "http://foo.org//"); + assert.equal(libUtil.join("http://foo.org//", "."), "http://foo.org//"); assert.equal(libUtil.join("//www.example.com", ""), "//www.example.com/"); assert.equal(libUtil.join("//www.example.com", "."), "//www.example.com/"); - assert.equal(libUtil.join("http://foo.org/a", "b"), "http://foo.org/a/b"); assert.equal(libUtil.join("http://foo.org/a/", "b"), "http://foo.org/a/b"); - assert.equal(libUtil.join("http://foo.org/a//", "b"), "http://foo.org/a/b"); + assert.equal(libUtil.join("http://foo.org/a//", "b"), "http://foo.org/a//b"); assert.equal(libUtil.join("http://foo.org/a", "b/"), "http://foo.org/a/b/"); - assert.equal(libUtil.join("http://foo.org/a", "b//"), "http://foo.org/a/b/"); + assert.equal(libUtil.join("http://foo.org/a", "b//"), "http://foo.org/a/b//"); assert.equal(libUtil.join("http://foo.org/a/", "/b"), "http://foo.org/b"); - assert.equal(libUtil.join("http://foo.org/a//", "//b"), "http://b/"); + assert.equal(libUtil.join("http://foo.org/a//", "//b"), "http://b/"); assert.equal(libUtil.join("http://foo.org/a", ".."), "http://foo.org/"); assert.equal(libUtil.join("http://foo.org/a", "../b"), "http://foo.org/b"); - assert.equal(libUtil.join("http://foo.org/a/b", "../c"), "http://foo.org/a/c"); + assert.equal( + libUtil.join("http://foo.org/a/b", "../c"), + "http://foo.org/a/c" + ); - assert.equal(libUtil.join("http://foo.org/a", "."), "http://foo.org/a"); + assert.equal(libUtil.join("http://foo.org/a", "."), "http://foo.org/a/"); assert.equal(libUtil.join("http://foo.org/a", "./b"), "http://foo.org/a/b"); - assert.equal(libUtil.join("http://foo.org/a/b", "./c"), "http://foo.org/a/b/c"); - - assert.equal(libUtil.join("http://foo.org/a", "http://www.example.com/"), "http://www.example.com/"); - assert.equal(libUtil.join("http://foo.org/a", "data:foo,bar"), "data:foo,bar"); - + assert.equal( + libUtil.join("http://foo.org/a/b", "./c"), + "http://foo.org/a/b/c" + ); + + assert.equal( + libUtil.join("http://foo.org/a", "http://www.example.com/"), + "http://www.example.com/" + ); + assert.equal( + libUtil.join("http://foo.org/a", "data:foo,bar"), + "data:foo,bar" + ); assert.equal(libUtil.join("http://foo.org/", "a"), "http://foo.org/a"); assert.equal(libUtil.join("http://foo.org/", "a"), "http://foo.org/a"); - assert.equal(libUtil.join("http://foo.org//", "a"), "http://foo.org/a"); + assert.equal(libUtil.join("http://foo.org//", "a"), "http://foo.org//a"); assert.equal(libUtil.join("http://foo.org/", "/a"), "http://foo.org/a"); assert.equal(libUtil.join("http://foo.org/", "/a"), "http://foo.org/a"); assert.equal(libUtil.join("http://foo.org//", "/a"), "http://foo.org/a"); - - assert.equal(libUtil.join("http://", "www.example.com"), "http://www.example.com/"); - assert.equal(libUtil.join("file:///", "www.example.com"), "file:///www.example.com"); - assert.equal(libUtil.join("http://", "ftp://example.com"), "ftp://example.com"); - - assert.equal(libUtil.join("http://www.example.com/", "//foo.org/bar"), "http://foo.org/bar"); - assert.equal(libUtil.join("//www.example.com", "//foo.org/bar"), "//foo.org/bar"); + assert.equal( + libUtil.join("http://www.example.com/", "//foo.org/bar"), + "http://foo.org/bar" + ); + assert.equal( + libUtil.join("//www.example.com", "//foo.org/bar"), + "//foo.org/bar" + ); }; // TODO Issue #128: Define and test this function properly. -exports["test relative()"] = function(assert) { +exports["test relative()"] = function (assert) { assert.equal(libUtil.relative("/the/root", "/the/root/one.js"), "one.js"); - assert.equal(libUtil.relative("http://the/root", "http://the/root/one.js"), "one.js"); - assert.equal(libUtil.relative("/the/root", "/the/rootone.js"), "../rootone.js"); - assert.equal(libUtil.relative("http://the/root", "http://the/rootone.js"), "../rootone.js"); - assert.equal(libUtil.relative("/the/root", "/therootone.js"), "/therootone.js"); - assert.equal(libUtil.relative("http://the/root", "/therootone.js"), "/therootone.js"); + assert.equal( + libUtil.relative("http://the/root", "http://the/root/one.js"), + "one.js" + ); + assert.equal( + libUtil.relative("/the/root", "/the/rootone.js"), + "../rootone.js" + ); + assert.equal( + libUtil.relative("http://the/root", "http://the/rootone.js"), + "../rootone.js" + ); + assert.equal( + libUtil.relative("/the/root", "/therootone.js"), + "../../therootone.js" + ); + assert.equal( + libUtil.relative("http://the/root", "/therootone.js"), + "/therootone.js" + ); assert.equal(libUtil.relative("", "/the/root/one.js"), "/the/root/one.js"); assert.equal(libUtil.relative(".", "/the/root/one.js"), "/the/root/one.js"); @@ -225,34 +231,72 @@ exports["test relative()"] = function(assert) { assert.equal(libUtil.relative("/", "the/root/one.js"), "the/root/one.js"); }; -exports["test computeSourceURL"] = function(assert) { +exports["test computeSourceURL"] = function (assert) { // Tests with sourceMapURL. - assert.equal(libUtil.computeSourceURL("", "src/test.js", "http://example.com/"), - "http://example.com/src/test.js"); - assert.equal(libUtil.computeSourceURL(undefined, "src/test.js", "http://example.com/"), - "http://example.com/src/test.js"); - assert.equal(libUtil.computeSourceURL("src", "test.js", "http://example.com/"), - "http://example.com/src/test.js"); - assert.equal(libUtil.computeSourceURL("src/", "test.js", "http://example.com/"), - "http://example.com/src/test.js"); - assert.equal(libUtil.computeSourceURL("src", "/test.js", "http://example.com/"), - "http://example.com/src/test.js"); - assert.equal(libUtil.computeSourceURL("http://mozilla.com/", "src/test.js", "http://example.com/"), - "http://mozilla.com/src/test.js"); - assert.equal(libUtil.computeSourceURL("", "test.js", "http://example.com/src/test.js.map"), - "http://example.com/src/test.js"); + assert.equal( + libUtil.computeSourceURL("", "src/test.js", "http://example.com/"), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL(undefined, "src/test.js", "http://example.com/"), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL("src", "test.js", "http://example.com/"), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL("src/", "test.js", "http://example.com/"), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL("src", "/test.js", "http://example.com/"), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL( + "http://mozilla.com/", + "src/test.js", + "http://example.com/" + ), + "http://mozilla.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL( + "", + "test.js", + "http://example.com/src/test.js.map" + ), + "http://example.com/src/test.js" + ); + assert.equal( + libUtil.computeSourceURL( + "", + "/test.js", + "http://example.com/src/test.js.map" + ), + "http://example.com/test.js" + ); // Legacy code won't pass in the sourceMapURL. assert.equal(libUtil.computeSourceURL("", "src/test.js"), "src/test.js"); - assert.equal(libUtil.computeSourceURL(undefined, "src/test.js"), "src/test.js"); + assert.equal( + libUtil.computeSourceURL(undefined, "src/test.js"), + "src/test.js" + ); assert.equal(libUtil.computeSourceURL("src", "test.js"), "src/test.js"); assert.equal(libUtil.computeSourceURL("src/", "test.js"), "src/test.js"); assert.equal(libUtil.computeSourceURL("src", "/test.js"), "src/test.js"); assert.equal(libUtil.computeSourceURL("src", "../test.js"), "test.js"); - assert.equal(libUtil.computeSourceURL("src/dir", "../././../test.js"), "test.js"); + assert.equal( + libUtil.computeSourceURL("src/dir", "../././../test.js"), + "test.js" + ); // This gives different results with the old algorithm and the new // spec-compliant algorithm. - assert.equal(libUtil.computeSourceURL("http://example.com/dir", "/test.js"), - "http://example.com/dir/test.js"); + assert.equal( + libUtil.computeSourceURL("http://example.com/dir", "/test.js"), + "http://example.com/dir/test.js" + ); }; diff --git a/test/util.js b/test/util.js index f0484320..665e70e2 100644 --- a/test/util.js +++ b/test/util.js @@ -26,22 +26,36 @@ const util = require("../lib/util"); // // ONE.foo=function(a){return baz(a);}; // TWO.inc=function(a){return a+1;}; -exports.testGeneratedCode = " ONE.foo=function(a){return baz(a);};\n" + - " TWO.inc=function(a){return a+1;};"; +exports.testGeneratedCode = + " ONE.foo=function(a){return baz(a);};\n TWO.inc=function(a){return a+1;};"; exports.testMap = { version: 3, file: "min.js", names: ["bar", "baz", "n"], sources: ["one.js", "two.js"], sourceRoot: "/the/root", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA" + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; + +exports.testMapWithIgnoreList = { + version: 3, + file: "min.js", + names: ["bar", "baz", "n"], + sources: ["one.js", "two.js"], + sourceRoot: "/the/root", + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", + x_google_ignoreList: [0], +}; + exports.testMapNoSourceRoot = { version: 3, file: "min.js", names: ["bar", "baz", "n"], sources: ["one.js", "two.js"], - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA" + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; exports.testMapEmptySourceRoot = { version: 3, @@ -49,7 +63,8 @@ exports.testMapEmptySourceRoot = { names: ["bar", "baz", "n"], sources: ["one.js", "two.js"], sourceRoot: "", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA" + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; exports.testMapSingleSource = { version: 3, @@ -57,51 +72,42 @@ exports.testMapSingleSource = { names: ["bar", "baz"], sources: ["one.js"], sourceRoot: "", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID" + mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", }; exports.testMapEmptyMappings = { version: 3, file: "min.js", names: [], sources: ["one.js", "two.js"], - sourcesContent: [ - " ONE.foo = 1;", - " TWO.inc = 2;" - ], + sourcesContent: [" ONE.foo = 1;", " TWO.inc = 2;"], sourceRoot: "", - mappings: "" + mappings: "", }; exports.testMapEmptyMappingsRelativeSources = { version: 3, file: "min.js", names: [], sources: ["./one.js", "./two.js"], - sourcesContent: [ - " ONE.foo = 1;", - " TWO.inc = 2;" - ], + sourcesContent: [" ONE.foo = 1;", " TWO.inc = 2;"], sourceRoot: "/the/root", - mappings: "" + mappings: "", }; exports.testMapEmptyMappingsRelativeSources_generatedExpected = { version: 3, file: "min.js", names: [], sources: ["one.js", "two.js"], - sourcesContent: [ - " ONE.foo = 1;", - " TWO.inc = 2;" - ], + sourcesContent: [" ONE.foo = 1;", " TWO.inc = 2;"], sourceRoot: "/the/root", - mappings: "" + mappings: "", }; exports.testMapMultiSourcesMappingRefersSingleSourceOnly = { - version: 3, - file: "min.js", - names: ["bar", "baz"], - sources: ["one.js", "withoutMappings.js"], - sourceRoot: "", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID" + version: 3, + file: "min.js", + names: ["bar", "baz"], + sources: ["one.js", "withoutMappings.js"], + sourceRoot: "", + mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", }; // This mapping is identical to above, but uses the indexed format instead. exports.indexedTestMap = { @@ -111,51 +117,36 @@ exports.indexedTestMap = { { offset: { line: 0, - column: 0 + column: 0, }, map: { version: 3, - sources: [ - "one.js" - ], + sources: ["one.js"], sourcesContent: [ - " ONE.foo = function (bar) {\n" + - " return baz(bar);\n" + - " };", - ], - names: [ - "bar", - "baz" + " ONE.foo = function (bar) {\n return baz(bar);\n };", ], + names: ["bar", "baz"], mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", file: "min.js", - sourceRoot: "/the/root" - } + sourceRoot: "/the/root", + }, }, { offset: { line: 1, - column: 0 + column: 0, }, map: { version: 3, - sources: [ - "two.js" - ], - sourcesContent: [ - " TWO.inc = function (n) {\n" + - " return n + 1;\n" + - " };" - ], - names: [ - "n" - ], + sources: ["two.js"], + sourcesContent: [" TWO.inc = function (n) {\n return n + 1;\n };"], + names: ["n"], mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA", file: "min.js", - sourceRoot: "/the/root" - } - } - ] + sourceRoot: "/the/root", + }, + }, + ], }; exports.indexedTestMapDifferentSourceRoots = { version: 3, @@ -164,51 +155,101 @@ exports.indexedTestMapDifferentSourceRoots = { { offset: { line: 0, - column: 0 + column: 0, }, map: { version: 3, - sources: [ - "one.js" - ], + sources: ["one.js"], sourcesContent: [ - " ONE.foo = function (bar) {\n" + - " return baz(bar);\n" + - " };", - ], - names: [ - "bar", - "baz" + " ONE.foo = function (bar) {\n return baz(bar);\n };", ], + names: ["bar", "baz"], mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", file: "min.js", - sourceRoot: "/the/root" - } + sourceRoot: "/the/root", + }, }, { offset: { line: 1, - column: 0 + column: 0, }, map: { version: 3, - sources: [ - "two.js" - ], + sources: ["two.js"], + sourcesContent: [" TWO.inc = function (n) {\n return n + 1;\n };"], + names: ["n"], + mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA", + file: "min.js", + sourceRoot: "/different/root", + }, + }, + ], +}; +exports.indexedTestMapColumnOffset = { + version: 3, + file: "min.js", + sections: [ + { + offset: { + line: 0, + column: 0, + }, + map: { + version: 3, + sources: ["one.js"], sourcesContent: [ - " TWO.inc = function (n) {\n" + - " return n + 1;\n" + - " };" - ], - names: [ - "n" + " ONE.foo = function (bar) {\n return baz(bar);\n };", ], + names: ["bar", "baz"], + mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", + file: "min.js", + sourceRoot: "/the/root", + }, + }, + { + offset: { + line: 0, + // Previous section's last generated mapping is [32, Infinity), so + // we're placing this a bit after that. + column: 50, + }, + map: { + version: 3, + sources: ["two.js"], + sourcesContent: [" TWO.inc = function (n) {\n return n + 1;\n };"], + names: ["n"], mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA", file: "min.js", - sourceRoot: "/different/root" - } - } - ] + sourceRoot: "/the/root", + }, + }, + ], +}; +// This mapping is for testing a case where the mapped position is at the +// section offset. +exports.indexedTestMapAtOffsetBoundary = { + version: 3, + file: "min.js", + sections: [ + { + offset: { + line: 0, + column: 0, + }, + map: { + version: 3, + sources: ["one.js"], + sourcesContent: [ + "ONE.foo = function (bar) {\n return baz(bar);\n };", + ], + names: ["bar", "baz"], + mappings: "AAAA", + file: "min.js", + sourceRoot: "/the/root", + }, + }, + ], }; exports.testMapWithSourcesContent = { version: 3, @@ -216,15 +257,12 @@ exports.testMapWithSourcesContent = { names: ["bar", "baz", "n"], sources: ["one.js", "two.js"], sourcesContent: [ - " ONE.foo = function (bar) {\n" + - " return baz(bar);\n" + - " };", - " TWO.inc = function (n) {\n" + - " return n + 1;\n" + - " };" + " ONE.foo = function (bar) {\n return baz(bar);\n };", + " TWO.inc = function (n) {\n return n + 1;\n };", ], sourceRoot: "/the/root", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA" + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; exports.testMapRelativeSources = { version: 3, @@ -232,54 +270,79 @@ exports.testMapRelativeSources = { names: ["bar", "baz", "n"], sources: ["./one.js", "./two.js"], sourcesContent: [ - " ONE.foo = function (bar) {\n" + - " return baz(bar);\n" + - " };", - " TWO.inc = function (n) {\n" + - " return n + 1;\n" + - " };" + " ONE.foo = function (bar) {\n return baz(bar);\n };", + " TWO.inc = function (n) {\n return n + 1;\n };", ], sourceRoot: "/the/root", - mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA" + mappings: + "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", }; exports.emptyMap = { version: 3, file: "min.js", names: [], sources: [], - mappings: "" + mappings: "", }; exports.mapWithSourcelessMapping = { version: 3, file: "example.js", names: [], sources: ["example.js"], - mappings: "AAgCA,C" + mappings: "AAgCA,C", }; - -function assertMapping(generatedLine, generatedColumn, originalSource, - originalLine, originalColumn, name, bias, map, assert, - dontTestGenerated, dontTestOriginal) { +function assertMapping( + generatedLine, + generatedColumn, + originalSource, + originalLine, + originalColumn, + name, + bias, + map, + assert, + dontTestGenerated, + dontTestOriginal +) { if (!dontTestOriginal) { const origMapping = map.originalPositionFor({ line: generatedLine, column: generatedColumn, - bias + bias, }); - assert.equal(origMapping.name, name, - "Incorrect name, expected " + JSON.stringify(name) - + ", got " + JSON.stringify(origMapping.name)); - assert.equal(origMapping.line, originalLine, - "Incorrect line, expected " + JSON.stringify(originalLine) - + ", got " + JSON.stringify(origMapping.line)); - assert.equal(origMapping.column, originalColumn, - "Incorrect column, expected " + JSON.stringify(originalColumn) - + ", got " + JSON.stringify(origMapping.column)); + assert.equal( + origMapping.name, + name, + "Incorrect name, expected " + + JSON.stringify(name) + + ", got " + + JSON.stringify(origMapping.name) + ); + assert.equal( + origMapping.line, + originalLine, + "Incorrect line, expected " + + JSON.stringify(originalLine) + + ", got " + + JSON.stringify(origMapping.line) + ); + assert.equal( + origMapping.column, + originalColumn, + "Incorrect column, expected " + + JSON.stringify(originalColumn) + + ", got " + + JSON.stringify(origMapping.column) + ); let expectedSource; - if (originalSource && map.sourceRoot && originalSource.indexOf(map.sourceRoot) === 0) { + if ( + originalSource && + map.sourceRoot && + originalSource.indexOf(map.sourceRoot) === 0 + ) { expectedSource = originalSource; } else if (originalSource) { expectedSource = map.sourceRoot @@ -289,9 +352,14 @@ function assertMapping(generatedLine, generatedColumn, originalSource, expectedSource = null; } - assert.equal(origMapping.source, expectedSource, - "Incorrect source, expected " + JSON.stringify(expectedSource) - + ", got " + JSON.stringify(origMapping.source)); + assert.equal( + origMapping.source, + expectedSource, + "Incorrect source, expected " + + JSON.stringify(expectedSource) + + ", got " + + JSON.stringify(origMapping.source) + ); } if (!dontTestGenerated) { @@ -299,14 +367,24 @@ function assertMapping(generatedLine, generatedColumn, originalSource, source: originalSource, line: originalLine, column: originalColumn, - bias + bias, }); - assert.equal(genMapping.line, generatedLine, - "Incorrect line, expected " + JSON.stringify(generatedLine) - + ", got " + JSON.stringify(genMapping.line)); - assert.equal(genMapping.column, generatedColumn, - "Incorrect column, expected " + JSON.stringify(generatedColumn) - + ", got " + JSON.stringify(genMapping.column)); + assert.equal( + genMapping.line, + generatedLine, + "Incorrect line, expected " + + JSON.stringify(generatedLine) + + ", got " + + JSON.stringify(genMapping.line) + ); + assert.equal( + genMapping.column, + generatedColumn, + "Incorrect column, expected " + + JSON.stringify(generatedColumn) + + ", got " + + JSON.stringify(genMapping.column) + ); } } exports.assertMapping = assertMapping; @@ -314,40 +392,74 @@ exports.assertMapping = assertMapping; function assertEqualMaps(assert, actualMap, expectedMap) { assert.equal(actualMap.version, expectedMap.version, "version mismatch"); assert.equal(actualMap.file, expectedMap.file, "file mismatch"); - assert.equal(actualMap.names.length, - expectedMap.names.length, - "names length mismatch: " + - actualMap.names.join(", ") + " != " + expectedMap.names.join(", ")); + assert.equal( + actualMap.names.length, + expectedMap.names.length, + "names length mismatch: " + + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") + ); for (let i = 0; i < actualMap.names.length; i++) { - assert.equal(actualMap.names[i], - expectedMap.names[i], - "names[" + i + "] mismatch: " + - actualMap.names.join(", ") + " != " + expectedMap.names.join(", ")); + assert.equal( + actualMap.names[i], + expectedMap.names[i], + "names[" + + i + + "] mismatch: " + + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") + ); } - assert.equal(actualMap.sources.length, - expectedMap.sources.length, - "sources length mismatch: " + - actualMap.sources.join(", ") + " != " + expectedMap.sources.join(", ")); + assert.equal( + actualMap.sources.length, + expectedMap.sources.length, + "sources length mismatch: " + + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") + ); for (let i = 0; i < actualMap.sources.length; i++) { - assert.equal(actualMap.sources[i], - expectedMap.sources[i], - "sources[" + i + "] length mismatch: " + - actualMap.sources.join(", ") + " != " + expectedMap.sources.join(", ")); + assert.equal( + actualMap.sources[i], + expectedMap.sources[i], + "sources[" + + i + + "] length mismatch: " + + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") + ); } - assert.equal(actualMap.sourceRoot, - expectedMap.sourceRoot, - "sourceRoot mismatch: " + - actualMap.sourceRoot + " != " + expectedMap.sourceRoot); - assert.equal(actualMap.mappings, expectedMap.mappings, - "mappings mismatch:\nActual: " + actualMap.mappings + "\nExpected: " + expectedMap.mappings); + assert.equal( + actualMap.sourceRoot, + expectedMap.sourceRoot, + "sourceRoot mismatch: " + + actualMap.sourceRoot + + " != " + + expectedMap.sourceRoot + ); + assert.equal( + actualMap.mappings, + expectedMap.mappings, + "mappings mismatch:\nActual: " + + actualMap.mappings + + "\nExpected: " + + expectedMap.mappings + ); if (actualMap.sourcesContent) { - assert.equal(actualMap.sourcesContent.length, - expectedMap.sourcesContent.length, - "sourcesContent length mismatch"); + assert.equal( + actualMap.sourcesContent.length, + expectedMap.sourcesContent.length, + "sourcesContent length mismatch" + ); for (let i = 0; i < actualMap.sourcesContent.length; i++) { - assert.equal(actualMap.sourcesContent[i], - expectedMap.sourcesContent[i], - "sourcesContent[" + i + "] mismatch"); + assert.equal( + actualMap.sourcesContent[i], + expectedMap.sourcesContent[i], + "sourcesContent[" + i + "] mismatch" + ); } } } diff --git a/wasm-mappings/.gitignore b/wasm-mappings/.gitignore new file mode 100644 index 00000000..143b1ca0 --- /dev/null +++ b/wasm-mappings/.gitignore @@ -0,0 +1,4 @@ + +/target/ +**/*.rs.bk +Cargo.lock diff --git a/wasm-mappings/CONTRIBUTING.md b/wasm-mappings/CONTRIBUTING.md new file mode 100644 index 00000000..d67cd208 --- /dev/null +++ b/wasm-mappings/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# Contributing to `source-map-mappings` + +## Building + +To build the core library for the host target (for use with testing): + +``` +$ cargo build +``` + +To build for WebAssembly, ensure that you have the `wasm32-unknown-unknown` target: + +``` +$ rustup update +$ rustup target add wasm32-unknown-unknown --toolchain nightly +``` + +Then, cross compile to a `.wasm` file via the WebAssembly API crate: + +``` +$ cd source-map-mappings-wasm-api/ +$ ./build.py -o output.wasm +``` + +The `build.py` script handles shrinking the size of the resulting `.wasm` file +for you, with `wasm-gc`, `wasm-snip`, and `wasm-opt`. + +For more details, run: + +``` +$ ./build.py --help +``` + +## Testing + +To run all the tests: + +``` +$ cargo test +``` + +## Automatic code formatting + +We use [`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) to enforce a +consistent code style across the whole code base. + +You can install the latest version of `rustfmt` with this command: + +``` +$ rustup update nightly +$ cargo install -f rustfmt-nightly +``` + +Ensure that `~/.cargo/bin` is on your path. + +Once that is taken care of, you can (re)format all code by running this command: + +``` +$ cargo fmt +``` diff --git a/wasm-mappings/Cargo.toml b/wasm-mappings/Cargo.toml new file mode 100644 index 00000000..6e075f37 --- /dev/null +++ b/wasm-mappings/Cargo.toml @@ -0,0 +1,30 @@ +[package] +authors = [ + "Nick Fitzgerald ", + "Tom Tromey ", +] +categories = [ + "development-tools::debugging", + "parser-implementations", +] +description = "Parse the `mappings` string from a source map." +keywords = [ + "sourcemap", + "source", + "map", + "vlq", +] +license = "BSD-3-Clause" +name = "source-map-mappings" +readme = "./README.md" +repository = "https://github.com/mozilla/source-map" +version = "0.5.0" + +[dependencies] +rand = "0.4.1" +vlq = "0.5.1" + +[dev-dependencies] +quickcheck = "0.5.0" +[profile.release] +debug = true diff --git a/wasm-mappings/README.md b/wasm-mappings/README.md new file mode 100644 index 00000000..2bd6d943 --- /dev/null +++ b/wasm-mappings/README.md @@ -0,0 +1,29 @@ +# `source-map-mappings` + +Parse the `"mappings"` string from a source map. + +This is intended to be compiled to WebAssembly and eventually used from the +[`mozilla/source-map`][source-map] library. This is **not** a general purpose +source maps library. + +[source-map]: https://github.com/mozilla/source-map + +- [Documentation](#documentation) +- [License](#license) +- [Contributing](#contributing) + +### Documentation + +[📚 Documentation on `docs.rs` 📚][docs] + +[docs]: https://docs.rs/source-map-mappings + +### License + +Licensed under [BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause). + +### Contributing + +See +[CONTRIBUTING.md](https://github.com/mozilla/source-map-mappings/blob/master/wasm-mappings/CONTRIBUTING.md) +for hacking. diff --git a/wasm-mappings/benches/bench.rs b/wasm-mappings/benches/bench.rs new file mode 100755 index 00000000..22de26a3 --- /dev/null +++ b/wasm-mappings/benches/bench.rs @@ -0,0 +1,18 @@ +#![feature(test)] + +extern crate source_map_mappings; +extern crate test; + +static FIXTURE: &'static [u8] = include_bytes!("./part-of-scala-js-source-map"); + +#[bench] +fn bench_parse_part_of_scala_js_source_map(b: &mut test::Bencher) { + b.iter(|| { + let mut mappings = source_map_mappings::parse_mappings::<()>(FIXTURE).unwrap(); + test::black_box( + mappings + .all_generated_locations_for(7, 2, None) + .count(), + ); + }); +} diff --git a/wasm-mappings/benches/part-of-scala-js-source-map b/wasm-mappings/benches/part-of-scala-js-source-map new file mode 100644 index 00000000..70e80876 --- /dev/null +++ b/wasm-mappings/benches/part-of-scala-js-source-map @@ -0,0 +1 @@ +AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;ACxDM,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,eAAAA,CAAAA,oBAAAA,EAAAA;IAAAC,oBAAAA,EAAAA,IAAAA;IAAAC,kBAAAA,EAAAA,IAAAA;;GAAAF,mBAAAA,C;;ACAA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,eAAAA,CAAAA,mBAAAA,EAAAA;IAAAG,mBAAAA,EAAAA,IAAAA;IAAAD,kBAAAA,EAAAA,IAAAA;;GAAAF,mBAAAA,C;;ACAA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,4BAAAA,EAAAA,WAAAA,EAAAA;aAAAI,KAAAA,GAAAA;MAAAJ,CAAAA,CAAAA,CAAAA,CAAAA,sBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAmB,KAAAK,YAAAA,GAAAA,IAAnBA;;IAAAD,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,sBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KACSA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAU,KAAAC,YAASA,CAAAA,UAAAA,CAAAA,EAAnBA;MADT;IAAAD,KAESA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAU,KAAAC,YAASA,CAAAA,UAAAA,CAAAA,EAAnBA;MAFT;IAAAD,KAGSA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAgB,KAAAC,YAASA,CAAAA,WAAAA,CAAAA,CAACA,KAADA,CAAzBA;MAHT;IAAAD,KAAkBA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAACA,OAADA,EAAAA;MAAC,KAAAC,YAAAA,UAADA;MAAAL,CAAAA,CAAAA,CAAAA,CAAAA,sBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAAlB;aAAAI,OAAAA,CAAkBA,KAAlBA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAkB,YAAAE,gCAAAA,CAAAA,CAAAA,KAAAA,CAAlBA;;IAAAF,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAJ,CAAAA,CAAAA,WAAAA,CAAAA,4BAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,sBAAAA,EAAAA;MAAAI,4BAAAA,EAAAA,IAAAA;MAAAG,sBAAAA,EAAAA,IAAAA;MAAAC,mBAAAA,EAAAA,IAAAA;MAAAL,mBAAAA,EAAAA,IAAAA;MAAAD,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;ACAA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,eAAAA,CAAAA,mBAAAA,EAAAA;IAAAQ,mBAAAA,EAAAA,IAAAA;IAAAN,kBAAAA,EAAAA,IAAAA;;GAAAF,mBAAAA,C;;ACAS,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,sBAAAA,EAAAA,WAAAA,EAAAA;aAAAO,KAAAA;MAAAP,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAO,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KACTA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAQ,UAAR;MADS;IAAAA,KAGTA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAQ,UAAR;MAHS;IAAAA,KAKTA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAMA,KAANA;MACF,IAAK,CAAAE,cAAAA,CAAAA,CAACA,KAADA,EAAIA,CAAJA,EAAOA,KAAEA,CAAAA,UAAAA,CAAAA,MAATA,CADHA;MALS;IAAAF,KASTA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAAMA,KAANA,EAAsBA,OAAtBA,EAAgCA,OAAhCA,EAA0CA;MACpC,IAAJG,YAAIA,GAAAA,OADoCA;MAE9B,IAAVC,eAAUA,GAAAA,CAAHA,OAAGA,GAACA,OAADA,CAF8BA;MAG5C,OAAS,CAAFD,YAAEA,GAAEA,eAAFA,CAATA,EAAiBA;QACf,IAAK,CAAAE,WAAAA,CAAAA,CAACA,KAACA,CAAAA,UAAAA,CAACA,YAADA,CAAFA,CADUA;QAEbF,YAAGA,GAAAA,CAADA,YAACA,GAACA,CAADA,CAFUA;OAH2B;KAA1C,CATS;IAAAH,KAAaA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAAP,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAAb;IAAAO,KASTA,CAAAA,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA;cAAAM,SAAAA,CAAAA,MAAAA;;UASA,YAAAC,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAAF,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YAbA,IAAAZ,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,cAAAA,CAAAA;0BAAAe,YAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;aAaA;WATA;;sBAAAN,cAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;;;MATS;aAAAF,OAAAA,GAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAa,YAAAS,UAAAA,CAAAA,EAAbA;;IAAAT,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAP,CAAAA,CAAAA,WAAAA,CAAAA,sBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAO,sBAAAA,EAAAA,IAAAA;MAAAC,mBAAAA,EAAAA,IAAAA;MAAAL,mBAAAA,EAAAA,IAAAA;MAAAD,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;ACAT,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,qBAAAA,EAAAA,WAAAA,EAAAA;aAAAiB,KAAAA,GAAAA;MAAAjB,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAY,KAAAkB,aAAAA,GAAAA,IAAZA;MAAgC,KAAAC,kBAAAA,GAAAA,KAAhCA;MAgBA,KAAAC,iBAAAA,GAAAA,KAhBAA;;IAAAH,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAOSA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA,EAAgBA;MAC3B,KAAAC,aAAUA,CAAAA,WAAAA,CAAAA,CAACA,KAADA,CADiBA;MAE3B,IAAc,CAAV,KAAAC,kBAAUA,IAAKA,CAAFA,KAAEA,KAAGA,EAAHA,CAALA,CAAdA;QAA0B,IAAK,CAAAE,UAAAA,CAAAA,EAA/BA;;;OAF2B;KAAhB,CAPT;IAAAJ,KAYAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAAOA,KAAPA;MAAkB,WAAlB;MAZA;IAAAA,KAaAA,CAAAA,SAAAA,CAAAA,uDAAAA,CAAAA,GAAAA,UAAOA,OAAPA;MAA4B,WAA5B;MAbA;IAAAA,KAcAA,CAAAA,SAAAA,CAAAA,yDAAAA,CAAAA,GAAAA,UAAOA,OAAPA,EAA0BA,SAA1BA,EAAsCA,OAAtCA;MAAkD,WAAlD;MAdA;IAAAA,KAgBAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;kBAAAG,iBAAAA;MAhBA;IAAAH,KAgBAA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAhBAA,OAgBAA;WAAAG,iBAAAA,GAAAA,OAAAA;MAhBA;IAAAH,KAiBAA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAK,aAAAA,CAAAA,EAAfA;MAjBA;IAAAL,KAkBAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAa,IAAS,CAAAM,gBAAAA,CAAAA,CAAEA,IAAFA,CAAtBA;MAlBA;IAAAN,KAmBAA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,IAAS,CAAAM,gBAAAA,CAAAA,CAAEA,KAAFA,CAAxBA;MAnBA;IAAAN,KAqBAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAA0B,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA/BA;MArBA;IAAAP,KAsBAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAuB,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA5BA;MAtBA;IAAAP,KAuBAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAsB,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA3BA;MAvBA;IAAAP,KAwBAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAuB,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA5BA;MAxBA;IAAAP,KAyBAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAwB,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA7BA;MAzBA;IAAAP,KA0BAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAyB,IAAK,CAAAO,WAAAA,CAAAA,CAACA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAHA,CAA9BA;MA1BA;IAAAP,KA2BAA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAA8B,IAAK,CAAAO,WAAAA,CAAAA,CAACA,iBAADA,CAAnCA;MA3BA;IAAAP,KA4BAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAyB,IAAM,CAAFQ,KAAEA,KAAGA,IAAHA,CAANA;QAAe,IAAK,CAAAD,WAAAA,CAAAA,CAACA,MAADA,CAApBA;;QAAkC,IAAW,CAAAE,iBAAAA,CAAAA,CAACA,KAADA,CAA7CA;OAAzB;MA5BA;IAAAT,KA6BAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAyB,IAAM,CAAFU,KAAEA,KAAGA,IAAHA,CAANA;QAAe,IAAK,CAAAH,WAAAA,CAAAA,CAACA,MAADA,CAApBA;;QAAkC,IAAK,CAAAA,WAAAA,CAAAA,CAACA,KAAEA,CAAAA,QAAAA,EAAHA,CAAvCA;OAAzB;MA7BA;IAAAP,KA+BUA,CAAAA,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA,EAAyBA;MACzB,IAARW,gBAAQA,GAAAA,CAAAA,CAAAA,cAAAA,CAAAA,CAAAA,CAAAA,UAAAA,CAAAA,YAAAA,CAAAA,CAAAA,KAAAA,EAAAA,CAAgBA,KAAEA,CAAAA,MAAlBA,CAAAA,CADyBA;yGAE3B5B,CAAAA,CAAAA,CAAAA,CAAAA,cAAAA,CAAAA,CAAAA,gBAAAA,CAAAA,CAAAA,CAAAA,CAF2BA,EAEnBA,KAAEA,CAAAA,MAFiBA;MAE9B,gBAAAA,CAAAA,CAAAA,CAAAA,CAAAA,4CAAAA,CAAAA,EAAAA,CAAAA,kCAAAA,CAAAA,CAAAA,IAAAA,EAAAA,KAAAA,EAAAA,gBAAAA,CAF8BA;MAE9B,MAAA6B,oCAAAA,CAAAA,CAAAA,KAAAA,CAF8BA;MAIrC,IAAK,CAAAd,YAAAA,CAAAA,CAACA,gBAADA,CAJgCA;KAAzB,CA/BV;IAAAE,KAsCAA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA;MAAkB,IAAK,CAAAL,WAAAA,CAAAA,CAACA,EAADA,CAAvBA;MAtCA;IAAAK,KAuCAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAA4BA;MAAE,IAAK,CAAAa,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAC,YAAAA,CAAAA,EAAnBA;KAA5B,CAvCA;IAAAd,KAwCAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAAyBA;MAAE,IAAK,CAAAe,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAD,YAAAA,CAAAA,EAAnBA;KAAzB,CAxCA;IAAAd,KAyCAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAAwBA;MAAE,IAAK,CAAAgB,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAF,YAAAA,CAAAA,EAAnBA;KAAxB,CAzCA;IAAAd,KA0CAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAAyBA;MAAE,IAAK,CAAAiB,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAH,YAAAA,CAAAA,EAAnBA;KAAzB,CA1CA;IAAAd,KA2CAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAA0BA;MAAE,IAAK,CAAAkB,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAJ,YAAAA,CAAAA,EAAnBA;KAA1B,CA3CA;IAAAd,KA4CAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAA2BA;MAAE,IAAK,CAAAmB,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAL,YAAAA,CAAAA,EAAnBA;KAA3B,CA5CA;IAAAd,KA6CAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAA2BA;MAAE,IAAK,CAAAO,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAO,YAAAA,CAAAA,EAAnBA;KAA3B,CA7CA;IAAAd,KA8CAA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAA2BA;MAAE,IAAK,CAAAoB,WAAAA,CAAAA,CAACA,KAADA,CAAPA;MAAY,IAAO,CAAAN,YAAAA,CAAAA,EAAnBA;KAA3B,CA9CA;IAAAd,KAgDAA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAAOA,UAAPA,EAAuBA,QAAvBA;MAAoD,IAAK,CAAAO,WAAAA,CAAAA,CAACA,QAADA,CAAzDA;MAhDA;IAAAP,KAiDAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAAOA,KAAPA,EAAkBA,UAAlBA,EAAkCA,QAAlCA;MAA+D,IAAK,CAAAO,WAAAA,CAAAA,CAACA,QAADA,CAApEA;MAjDA;IAAAP,KAkDAA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAAOA,UAAPA,EAAuBA,QAAvBA;MAAoD,IAAK,CAAAO,WAAAA,CAAAA,CAACA,QAADA,CAAzDA;MAlDA;IAAAP,KAmDAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAAOA,KAAPA,EAAkBA,UAAlBA,EAAkCA,QAAlCA;MAA+D,IAAK,CAAAO,WAAAA,CAAAA,CAACA,QAADA,CAApEA;MAnDA;IAAAP,KAAAA,CAAAA,SAAAA,CAAAA,wDAAAA,CAAAA,GAAAA,ULGOA,OKHPA,ELG0BA,SKH1BA,ELGsCA,OKHtCA;kBAAAqB,yDAAAA,CAAAA,CAAAA,OAAAA,EAAAA,SAAAA,EAAAA,OAAAA,CAAAA;;IAAArB,KAAAA,CAAAA,SAAAA,CAAAA,sDAAAA,CAAAA,GAAAA,ULEOA,OKFPA;kBAAAsB,uDAAAA,CAAAA,CAAAA,OAAAA,CAAAA;;IAAAtB,KAAAA,CAAAA,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,ULCOA,KKDPA;kBAAAuB,gCAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;IAAAvB,KAAWA,CAAAA,SAAAA,CAAAA,kCAAAA,CAAAA,GAAAA,UAACA,QAADA,EAAqBA,aAArBA,EAAyCA,WAAzCA,EAAAA;MAAC,KAAAC,aAAAA,WAADA;MAAqB,KAAAC,kBAAAA,gBAArBA;MAAAnB,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EACcA,QADdA,CAAAA;MAgBX,KAAAoB,iBAAAA,GAAWA,KAhBAA;;MAAX;IAAAH,KAIAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAAKA,OAALA,EAAAA;MAA0B,KAAAwB,kCAAAA,CAAAA,CAAKA,OAALA,EAAUA,KAAVA,EAAiBA,EAAjBA,CAA1BA;;MAJA;IAAAxB,KAKAA,CAAAA,SAAAA,CAAAA,iCAAAA,CAAAA,GAAAA,UAAKA,OAALA,EAAwBA,aAAxBA,EAAAA;MAA8C,KAAAwB,kCAAAA,CAAAA,CAAKA,OAALA,EAAUA,aAAVA,EAAqBA,EAArBA,CAA9CA;;MALA;IAAAxB,KAcAA,CAAAA,SAAAA,CAAAA,MAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA;cAAAJ,SAAAA,CAAAA,MAAAA;;UAFA,YAAAC,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAA0B,gCAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YACA,IAAAxC,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,wBAAAA,CAAAA;0BAAAuC,uDAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;aADA;WAEA;;sBAAAD,yDAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;;;MAdA;IAAArB,KAgBAA,CAAAA,SAAAA,CAAAA,QAAAA,GAAAA;kBAAAK,aAAAA,CAAAA,EAAAA;MAhBA;IAAAL,KAgBAA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAAA,KAAAA;kBAAAM,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAhBA;IAAAN,KAiBAA,CAAAA,SAAAA,CAAAA,UAAAA,GAAAA;kBAAAyB,eAAAA,CAAAA,EAAAA;MAjBA;IAAAzB,KAkBAA,CAAAA,SAAAA,CAAAA,QAAAA,GAAAA;kBAAA0B,aAAAA,CAAAA,EAAAA;MAlBA;IAAA1B,KAmBAA,CAAAA,SAAAA,CAAAA,UAAAA,GAAAA;kBAAA2B,eAAAA,CAAAA,EAAAA;MAnBA;IAAA3B,KA6BAA,CAAAA,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA;MARA,YAAAH,KAAAA,CAAAA,KAAAA,SAAAA,CAAAA;oBAAAgB,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;QACA,YAAAhB,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA,EAAAA;sBAAAkB,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;UACA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CADAA;UAEA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAFAA;UAGA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAHAA;UAIA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAJAA;;UAMA,YAAAtB,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAAU,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YADA,IAAAxB,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,cAAAA,CAAAA;0BAAA6C,YAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;cAEA,IAAA7C,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,kBAAAA,CAAAA;4BAAAqC,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;eAFA;aACA;WANA;SADA;OAQA;MA7BA;IAAApB,KA8CAA,CAAAA,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;cAAAJ,SAAAA,CAAAA,MAAAA;;UARA,YAAAkB,YAAAA,CAAAA,EAQAA;;UAPA,YAAAjB,KAAAA,CAAAA,KAAAA,SAAAA,CAAAA;wBAAAgC,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YACA,YAAAhC,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA,EAAAA;0BAAAiC,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;cACA,YAAAC,aAAAA,CAAAA,CAAAA,KAAAA,CADAA;cAEA,YAAAC,aAAAA,CAAAA,CAAAA,KAAAA,CAFAA;cAGA,YAAAC,aAAAA,CAAAA,CAAAA,KAAAA,CAHAA;cAIA,YAAAC,aAAAA,CAAAA,CAAAA,KAAAA,CAJAA;;cAKA,YAAArC,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;4BAAAsC,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;gBACA,IAAApD,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,kBAAAA,CAAAA;8BAAAqD,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;iBADA;eALA;aADA;WAOA;;;;MA9CA;IAAApC,KAiDAA,CAAAA,SAAAA,CAAAA,MAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA;cAAAJ,SAAAA,CAAAA,MAAAA;;UADA,YAAAyC,cAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CACAA;;sBAAAC,gCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;;;MAjDA;IAAAtC,KAmDAA,CAAAA,SAAAA,CAAAA,MAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA;cAAAJ,SAAAA,CAAAA,MAAAA;;UADA,YAAA2C,cAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CACAA;;sBAAAC,gCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;;;MAnDA;aAAAxC,OAAAA,CAKAA,KALAA,EAKAA,KALAA,EAKAA,KALAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAKA,QAAAJ,SAAAA,CAAAA,MAAAA;;UADA,YAAAP,gCAAAA,CAAAA,CAAAA,KAAAA,CACAA;;sBAAAoD,iCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;UALW,YAAAjB,kCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAKXA;;;OALA;;IAAAxB,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAjB,CAAAA,CAAAA,WAAAA,CAAAA,qBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,4BAAAA,EAAAA;MAAAiB,qBAAAA,EAAAA,IAAAA;MAAAhB,oBAAAA,EAAAA,IAAAA;MAAAG,4BAAAA,EAAAA,IAAAA;MAAAG,sBAAAA,EAAAA,IAAAA;MAAAC,mBAAAA,EAAAA,IAAAA;MAAAL,mBAAAA,EAAAA,IAAAA;MAAAD,kBAAAA,EAAAA,IAAAA;;;EAiCKF,CAAAA,CAAAA,aAAAA,CAAAA,4CAAAA,EAAAA,WAAAA,EAAAA;aAAA2D,KAAAA,GAAAA;MAAA3D,CAAAA,CAAAA,CAAAA,CAAAA,yCAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;WAAA4D,YAAAA,GAAAA,IAAAA;WAAAC,gBAAAA,GAAAA,IAAAA;;IAAAF,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,yCAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAFA,KAAEA;WAAAG,mBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;IAAAH,KAAAA,CAAAA,SAAAA,CAAAA,mBAAAA,CAAAA,GAAAA;MACL,KAAAE,gBAASA,CAAAA,UAAAA,CAAHA,KAAGA,CAAAA,GAAEA,IAAAA,CAAAA,YAAQA,CAAAA,UAAAA,CAACA,KAADA,CADdA;;IAAAF,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,kBAAAA;WAAAI,WAAAA,CAAAA,CAAAA,CAAAA,CAAAA,EAAAA,CAAAA,MAAAA,CAAAA,CAAAA;aAAA/D,CAAAA,CAAAA,CAAAA,CAAAA,yBAAAA,CAAAA,CAAAA,iCAAAA,CAAAA,EAAAA;;IAAA2D,KAAAA,CAAAA,SAAAA,CAAAA,kCAAAA,CAAAA,GAAAA,UAAAA,UAAAA,EAAAA,OAAAA,EAAAA,WAAAA,EAAAA;WAAAC,YAAAA,UAAAA;WAAAC,gBAAAA,cAAAA;MAAA7D,CAAAA,CAAAA,CAAAA,CAAAA,yCAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;;aAAA2D,OAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;kBAAAK,kCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;IAAAL,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAA3D,CAAAA,CAAAA,WAAAA,CAAAA,4CAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,yCAAAA,EAAAA;MAAA2D,4CAAAA,EAAAA,IAAAA;MAAAM,oBAAAA,EAAAA,IAAAA;MAAAC,sBAAAA,EAAAA,IAAAA;MAAAC,yCAAAA,EAAAA,IAAAA;MAAAC,yBAAAA,EAAAA,IAAAA;MAAAC,iCAAAA,EAAAA,IAAAA;MAAAC,iBAAAA,EAAAA,IAAAA;MAAApE,kBAAAA,EAAAA,IAAAA;;KAjCL;GAAAF,mBAAAA,C;;ACAA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,eAAAA,CAAAA,sBAAAA,EAAAA;IAAAkE,sBAAAA,EAAAA,IAAAA;IAAAhE,kBAAAA,EAAAA,IAAAA;;GAAAF,mBAAAA,C;;ACsEA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,0CAAAA,EAAAA,WAAAA,EAAAA;aAAAuE,KAAAA;MAAAvE,CAAAA,CAAAA,CAAAA,CAAAA,qCAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAuE,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,qCAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAA8BA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAACA,KAADA,EAAAA;MAAAvE,CAAAA,CAAAA,CAAAA,CAAAA,qCAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAA8CA,KAA9CA,CAAAA;;MAA9B;IAAAuE,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAAC,WAAAA,CAAAA,CAAKA,IAALA,CAATA;;MADA;aAAAD,OAAAA,CACAA,KADAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACA,QAAA1D,SAAAA,CAAAA,MAAAA;;sBAAAG,UAAAA,CAAAA,EAAAA;;UAD8B,YAAAwD,WAAAA,CAAAA,CAAAA,KAAAA,CAC9BA;;;OADA;;IAAAD,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAvE,CAAAA,CAAAA,WAAAA,CAAAA,0CAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,qCAAAA,EAAAA;MAAAuE,0CAAAA,EAAAA,IAAAA;MAAAE,qCAAAA,EAAAA,IAAAA;MAAAC,4BAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AAhDA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,0BAAAA,EAAAA,WAAAA,EAAAA;aAAA6E,KAAAA;MAAA7E,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAA6E,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAeA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAASA,WAATA,EAAAA;MAAA7E,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAA4CA,WAA5CA,CAAAA;;MAAf;IAAA6E,KACAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAuB,IAAM,CAAFlD,KAAEA,KAAGA,IAAHA,CAANA;QAAe,IAAf,KAAe,OAAf;;QAA2B,IAA3B,KAA2B,GAAFA,KAAEA,CAAAA,QAAAA,EAA3BA;OAAvB;MAAkB,KAAA6C,WAAAA,CAAAA,CAAKA,KAALA,CAAlBA;;MADA;IAAAK,KAEAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAyB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAAzBA;;MAFA;IAAAK,KAGAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAsB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAAtBA;;MAHA;IAAAK,KAIAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAwB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAAxBA;;MAJA;IAAAK,KAKAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAuB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAAvBA;;MALA;IAAAK,KAMAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAqB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAArBA;;MANA;IAAAK,KAOAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,KAALA,EAAAA;MAAsB,KAAAL,WAAAA,CAAAA,CAAKA,CAAAA,CAAAA,EAAAA,CAAAA,KAAAA,CAAEA,CAAAA,QAAAA,EAAPA,CAAtBA;;MAPA;aAAAK,OAAAA,CAOAA,KAPAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAEA,YAAA/D,KAAAA,CAAAA,KAAAA,SAAAA,CAAAA;oBAAAgE,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;QACA,YAAAhE,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA,EAAAA;sBAAAiE,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;UACA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CADAA;UAEA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAFAA;UAGA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAHAA;UAIA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CAJAA;;UAFA,IAAAnF,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,kBAAAA,CAAAA;wBAAAoF,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YAMA,4BANA;WAEA;SADA;OAFA;;IAAAP,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAA7E,CAAAA,CAAAA,WAAAA,CAAAA,0BAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,qBAAAA,EAAAA;MAAA6E,0BAAAA,EAAAA,IAAAA;MAAAD,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;ACtBA,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,mBAAAA,EAAAA,WAAAA,EAAAA;aAAAqF,KAAAA,GAAAA;MAAArF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAoB,KAAAsF,cAAAA,GAAAA,KAApBA;;IAAAD,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAoBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAC,cAAAA;MAApB;IAAAD,KACAA,CAAAA,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;MAAgC,YAAAE,UAAAA,CAAAA,EAAhCA;MADA;IAAAF,KAGSA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACgB,QAAVrF,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,mBAAAA,CAAUA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,mBAAAA,CAAUA,CAAAA,UAAAA,CAAAA,EAA9BA,CAAVA,CADhBA;MAHT;IAAAqF,KAMSA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAmB,IAAI,KAAAE,UAAAA,CAAAA,EAAJA;QAAW,aAAX;;QAAuB,cAAvB;OAAnB;MANT;IAAAF,KAQSA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAW,IAAI,KAAAE,UAAAA,CAAAA,EAAJA;QAAW,WAAX;;QAAqB,WAArB;OAAX;MART;IAAAF,KAAOA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAC,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAAP;IAAAqF,KACAA,CAAAA,SAAAA,CAAAA,YAAAA,GAAAA;kBAAAG,iBAAAA,CAAAA,EAAAA;MADA;aAAAH,OAAAA,CAAOA,KAAPA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAO,YAAAP,WAAAA,CAAAA,CAAAA,KAAAA,CAAPA;;IAAAO,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAArF,CAAAA,CAAAA,WAAAA,CAAAA,mBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAqF,mBAAAA,EAAAA,IAAAA;MAAAnF,kBAAAA,EAAAA,IAAAA;;;;;;MAYA,KAAAuF,aAAAA,GAAAA,IAZAA;MAaA,KAAAC,aAAAA,GAAAA,IAbAA;MAcA,KAAAC,cAAAA,GAAAA,IAdAA;;;;IAYA,MAAAC,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAZA;IAaA,MAAAG,SAAAA,CAAAA,2BAAAA,CAAAA,GAAAA;kBAAAF,aAAAA;MAbA;IAcA,MAAAE,SAAAA,CAAAA,4BAAAA,CAAAA,GAAAA;kBAAAD,cAAAA;MAdA;IAgBA,MAAAC,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,UAAQA,gBAARA;MAAuC,IAAIC,gBAAJA;QAAkB,YAAAC,2BAAAA,CAAAA,EAAlBA;;QAA4B,YAAAC,4BAAAA,CAAAA,EAA5BA;OAAvC;MAhBA;IAkBA,MAAAH,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAA6B,IAAII,KAAJA;QAAO,aAAP;;QAAmB,cAAnB;OAA7B;MAlBA;IAWS,MAAAJ,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,mBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACT,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,eAAAA,CAAAA,CAAAA,GADLA;MAET,KAAAC,aAAAA,GAAOA,IAAAA,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAYA,IAAZA,CAFEA;MAGT,KAAAC,cAAAA,GAAQA,IAAAA,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAYA,KAAZA,CAHCA;;MAXT;IAYA,MAAAC,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAZA;IAaA,MAAAL,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAE,2BAAAA,CAAAA,EAAAA;MAbA;IAcA,MAAAF,SAAAA,CAAAA,KAAAA,GAAAA;kBAAAG,4BAAAA,CAAAA,EAAAA;MAdA;IAgBA,MAAAH,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAM,+BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAhBA;IAkBA,MAAAN,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAsF,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MAlBA;;;MAWS,YAAAnF,UAAAA,CAAAA,EAXTA;;;;;;;;EAWChB,CAAAA,CAAAA,cAAAA,CAAAA,mBAAAA,EAAAA,oBAAAA,CAXDA;GAAAA,mBAAAA,C;;AC6BM,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,gBAAAA,EAAAA,WAAAA,EAAAA;aAAAoG,KAAAA,GAAAA;MAAApG,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAiB,KAAAsF,cAAAA,GAAAA,CAAjBA;MACU,KAAAe,cAAAA,GAAAA,KADVA;;IAAAD,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAiBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAd,cAAAA;MAAjB;IAAAc,KACUA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAC,cAAAA;MADV;IAAAD,KAGGA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAc,YAAAE,UAAAA,CAAAA,EAAdA;MAHH;IAAAF,KAIGA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAE,UAAAA,CAAAA,EAAfA;MAJH;IAAAF,KAKNA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAa,YAAAE,UAAAA,CAAAA,EAAbA;MALM;IAAAF,KAMNA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAc,YAAAE,UAAAA,CAAAA,EAAdA;MANM;IAAAF,KAONA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAE,UAAAA,CAAAA,EAAfA;MAPM;IAAAF,KAQNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MAAgB,YAAAE,UAAAA,CAAAA,EAAhBA;MARM;IAAAF,KAUGA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACa,QAAPpG,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,gBAAAA,CAAOA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,gBAAAA,CAAOA,CAAAA,UAAAA,CAAAA,EAA3BA,CAAVA,CADbA;MAVH;IAAAoG,KAaGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAA6B,OAAjB,KAAAE,UAAAA,CAAAA,EAAiBA,CAAAA,QAAAA,EAA7BA;MAbH;IAAAF,KAAIA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAd,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACM,KAAAqG,cAAAA,GAAQA,IADdA;;MAAJ;aAAAD,OAAAA,CAAIA,KAAJA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAI,YAAAG,WAAAA,CAAAA,CAAAA,KAAAA,CAAJA;;IAAAH,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAApG,CAAAA,CAAAA,WAAAA,CAAAA,gBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAoG,gBAAAA,EAAAA,IAAAA;MAAAI,kBAAAA,EAAAA,IAAAA;MAAAtG,kBAAAA,EAAAA,IAAAA;;;;;;MAiBN,KAAAuF,aAAAA,GAAAA,IAjBMA;MAkBN,KAAAgB,kBAAAA,GAAAA,CAlBMA;MAmBN,KAAAC,kBAAAA,GAAAA,CAnBMA;;;;IAiBN,MAAAd,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAjBM;IAkBN,MAAAG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAlBM;IAmBN,MAAAb,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAnBM;IAqBN,MAAAd,SAAAA,CAAAA,4BAAAA,CAAAA,GAAAA,UAAQA,aAARA;MAAiC,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,gBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAASA,aAATA,CAAjCA;MArBM;IAsBN,MAAA4F,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA,UAAUA,KAAVA;MAAmD,OAAhB5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAgBA,CAAAA,cAAAA,CAAAA,CAACA,KAADA,CAAnDA;MAtBM;IAuBN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAmD,OAAzB5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAeA,CAAAA,+BAAAA,CAAAA,CAACA,KAADA,CAAUA,CAAAA,aAAAA,CAAAA,EAAnDA;MAvBM;IAgBA,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,gBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACN,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,YAAAA,CAAAA,CAAAA,GADRA;MAEN,KAAAgB,kBAAAA,GAAyBA,IAFnBA;MAGN,KAAAC,kBAAAA,GAAwBA,GAHlBA;;MAhBA;IAiBN,MAAAd,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAjBM;IAkBN,MAAAL,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAe,cAAAA,CAAAA,EAAAA;MAlBM;IAmBN,MAAAf,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAgB,cAAAA,CAAAA,EAAAA;MAnBM;IAqBN,MAAAhB,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAiB,4BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MArBM;IAsBN,MAAAjB,SAAAA,CAAAA,SAAAA,GAAAA,UAAAA,KAAAA;kBAAAkB,eAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAtBM;IAuBN,MAAAlB,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAkG,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MAvBM;;;MAgBA,YAAA/F,UAAAA,CAAAA,EAhBAA;;;;;;;;EAgBLhB,CAAAA,CAAAA,cAAAA,CAAAA,gBAAAA,EAAAA,iBAAAA,CAhBKA;GAAAA,mBAAAA,C;;AC3BN,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,qBAAAA,EAAAA,WAAAA,EAAAA;aAAAgH,KAAAA,GAAAA;MAAAhH,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAU,KAAAsF,cAAAA,GAAAA,CAAVA;;IAAA0B,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KACAA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAA0B,YAAA1B,cAA1BA;MADA;IAAA0B,KAGSA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACkB,QAAZhH,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,qBAAAA,CAAYA,IAAUA,CAANA,IAAAA,CAAAA,cAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,qBAAAA,CAAYA,CAAAA,cAAAA,CAAAA,EAAhCA,CAAVA,CADlBA;MAHT;IAAAgH,KAMSA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAC0B,OAA1BhH,CAAAA,CAAAA,CAAAA,CAAAA,MAA0BA,CAA1BA,YAA0BA,CAACA,IAAAA,CAAAA,cAADA,CAD1BA;MANT;IAAAgH,KAASA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAACA,SAADA,EAAAA;MAAC,KAAA1B,cAAAA,YAADA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAAT;IAAAgH,KACAA,CAAAA,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAC,cAAAA,CAAAA,EAAAA;MADA;aAAAD,OAAAA,CAASA,KAATA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAS,YAAAjC,WAAAA,CAAAA,CAAAA,KAAAA,CAATA;;IAAAiC,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAhH,CAAAA,CAAAA,WAAAA,CAAAA,qBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAgH,qBAAAA,EAAAA,IAAAA;MAAA9G,kBAAAA,EAAAA,IAAAA;;;;;;MAWA,KAAAuF,aAAAA,GAAAA,IAXAA;MAYA,KAAAgB,kBAAAA,GAAAA,CAZAA;MAaA,KAAAC,kBAAAA,GAAAA,CAbAA;MAiBA,KAAAQ,yBAAAA,GAAAA,CAjBAA;MAkBA,KAAAC,yBAAAA,GAAAA,CAlBAA;MAmBA,KAAAC,qBAAAA,GAAAA,CAnBAA;MAoBA,KAAAC,yBAAAA,GAAAA,CApBAA;MAqBA,KAAAC,sBAAAA,GAAAA,CArBAA;MAsBA,KAAAC,+BAAAA,GAAAA,CAtBAA;MAuBA,KAAAC,uBAAAA,GAAAA,CAvBAA;MAwBA,KAAAC,yBAAAA,GAAAA,CAxBAA;MAyBA,KAAAC,wBAAAA,GAAAA,CAzBAA;MA0BA,KAAAC,6BAAAA,GAAAA,CA1BAA;MA2BA,KAAAC,kBAAAA,GAAAA,CA3BAA;MA6BA,KAAAC,kBAAAA,GAAAA,CA7BAA;;;;IAWA,MAAAjC,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAXA;IAYA,MAAAG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAZA;IAaA,MAAAb,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAbA;IAeA,MAAAd,SAAAA,CAAAA,iCAAAA,CAAAA,GAAAA,UAAQA,aAARA;MAAiC,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAcA,aAAdA,CAAjCA;MAfA;IAiBA,MAAA4F,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA;kBAAAsB,yBAAAA;MAjBA;IAkBA,MAAAtB,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA;kBAAAuB,yBAAAA;MAlBA;IAmBA,MAAAvB,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;kBAAAwB,qBAAAA;MAnBA;IAoBA,MAAAxB,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA;kBAAAyB,yBAAAA;MApBA;IAqBA,MAAAzB,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA;kBAAA0B,sBAAAA;MArBA;IAsBA,MAAA1B,SAAAA,CAAAA,2BAAAA,CAAAA,GAAAA;kBAAA2B,+BAAAA;MAtBA;IAuBA,MAAA3B,SAAAA,CAAAA,mBAAAA,CAAAA,GAAAA;kBAAA4B,uBAAAA;MAvBA;IAwBA,MAAA5B,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA;kBAAA6B,yBAAAA;MAxBA;IAyBA,MAAA7B,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA;kBAAA8B,wBAAAA;MAzBA;IA0BA,MAAA9B,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAA+B,6BAAAA;MA1BA;IA2BA,MAAA/B,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAgC,kBAAAA;MA3BA;IA6BA,MAAAhC,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAiC,kBAAAA;MA7BA;IAgCA,MAAAjC,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,MAARA;MAA8C,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA9CA;MAhCA;IAiCA,MAAA4F,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,aAARA;MAAoD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAApDA;MAjCA;IAkCA,MAAA4F,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAMA,KAANA,EAAqBA,SAArBA;MAA6D,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA7DA;MAlCA;IAmCA,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAaA,KAAbA;MAAsD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAtDA;MAnCA;IAoCA,MAAA4F,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,UAAQA,KAARA;MAAiD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAjDA;MApCA;IAqCA,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAkD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAlDA;MArCA;IAsCA,MAAA4F,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA,UAAgBA,KAAhBA;MAAyD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAzDA;MAtCA;IAuCA,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAaA,KAAbA;MAAsD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAtDA;MAvCA;IAwCA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MAxCA;IAyCA,MAAA4F,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA,UAAgBA,KAAhBA;MAAyD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAzDA;MAzCA;IA0CA,MAAA4F,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,UAAeA,KAAfA;MAAwD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAxDA;MA1CA;IA2CA,MAAA4F,SAAAA,CAAAA,8BAAAA,CAAAA,GAAAA,UAAyBA,KAAzBA;MAAkE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAlEA;MA3CA;IA4CA,MAAA4F,SAAAA,CAAAA,6BAAAA,CAAAA,GAAAA,UAAwBA,KAAxBA;MAAiE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAjEA;MA5CA;IA6CA,MAAA4F,SAAAA,CAAAA,2BAAAA,CAAAA,GAAAA,UAAsBA,KAAtBA;MAA+D,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA/DA;MA7CA;IA8CA,MAAA4F,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAAWA,KAAXA;MAAoD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAApDA;MA9CA;IA+CA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MA/CA;IAgDA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MAhDA;IAiDA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MAjDA;IAkDA,MAAA4F,SAAAA,CAAAA,0BAAAA,CAAAA,GAAAA,UAAqBA,KAArBA;MAA8D,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA9DA;MAlDA;IAoDA,MAAA4F,SAAAA,CAAAA,uBAAAA,CAAAA,GAAAA,UAAkBA,KAAlBA;MAAwD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAxDA;MApDA;IAuDA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAkD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAlDA;MAvDA;IAwDA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAkD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAlDA;MAxDA;IAyDA,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAkD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAlDA;MAzDA;IA0DA,MAAA4F,SAAAA,CAAAA,qBAAAA,CAAAA,GAAAA,UAAgBA,KAAhBA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MA1DA;IA6DA,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAaA,MAAbA;MAAoD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAApDA;MA7DA;IA+DA,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAqC,OAAX,IAAO,CAAAkC,iCAAAA,CAAAA,CAACA,KAADA,CAAIA,CAAAA,aAAAA,CAAAA,EAArCA;MA/DA;IAUW,MAAAlC,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACX,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,YAAAA,CAAAA,CAAAA,GADHA;MAEX,KAAAgB,kBAAAA,GAAwBA,CAFbA;MAGX,KAAAC,kBAAAA,GAAwBA,GAHbA;MAOX,KAAAQ,yBAAAA,GAA+BA,CAPpBA;MAQX,KAAAC,yBAAAA,GAA+BA,CARpBA;MASX,KAAAC,qBAAAA,GAA2BA,CAThBA;MAUX,KAAAC,yBAAAA,GAA+BA,CAVpBA;MAWX,KAAAC,sBAAAA,GAA4BA,CAXjBA;MAYX,KAAAC,+BAAAA,GAAqCA,CAZ1BA;MAaX,KAAAC,uBAAAA,GAA6BA,CAblBA;MAcX,KAAAC,yBAAAA,GAA+BA,CAdpBA;MAeX,KAAAC,wBAAAA,GAA8BA,CAfnBA;MAgBX,KAAAC,6BAAAA,GAAmCA,CAhBxBA;MAiBX,KAAAC,kBAAAA,GAAwBA,CAjBbA;MAmBX,KAAAC,kBAAAA,GAAuBA,CAnBZA;;MAVX;IAWA,MAAAjC,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAXA;IAYA,MAAAL,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAmC,cAAAA,CAAAA,EAAAA;MAZA;IAaA,MAAAnC,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAoC,cAAAA,CAAAA,EAAAA;MAbA;IAeA,MAAApC,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAkC,iCAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAfA;IAiBA,MAAAlC,SAAAA,CAAAA,gBAAAA,GAAAA;kBAAAqC,qBAAAA,CAAAA,EAAAA;MAjBA;IAkBA,MAAArC,SAAAA,CAAAA,gBAAAA,GAAAA;kBAAAsC,qBAAAA,CAAAA,EAAAA;MAlBA;IAmBA,MAAAtC,SAAAA,CAAAA,YAAAA,GAAAA;kBAAAuC,iBAAAA,CAAAA,EAAAA;MAnBA;IAoBA,MAAAvC,SAAAA,CAAAA,gBAAAA,GAAAA;kBAAAwC,qBAAAA,CAAAA,EAAAA;MApBA;IAqBA,MAAAxC,SAAAA,CAAAA,aAAAA,GAAAA;kBAAAyC,kBAAAA,CAAAA,EAAAA;MArBA;IAsBA,MAAAzC,SAAAA,CAAAA,sBAAAA,GAAAA;kBAAA0C,2BAAAA,CAAAA,EAAAA;MAtBA;IAuBA,MAAA1C,SAAAA,CAAAA,cAAAA,GAAAA;kBAAA2C,mBAAAA,CAAAA,EAAAA;MAvBA;IAwBA,MAAA3C,SAAAA,CAAAA,gBAAAA,GAAAA;kBAAA4C,qBAAAA,CAAAA,EAAAA;MAxBA;IAyBA,MAAA5C,SAAAA,CAAAA,eAAAA,GAAAA;kBAAA6C,oBAAAA,CAAAA,EAAAA;MAzBA;IA0BA,MAAA7C,SAAAA,CAAAA,oBAAAA,GAAAA;kBAAA8C,yBAAAA,CAAAA,EAAAA;MA1BA;IA2BA,MAAA9C,SAAAA,CAAAA,SAAAA,GAAAA;kBAAA+C,cAAAA,CAAAA,EAAAA;MA3BA;IA6BA,MAAA/C,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAgD,cAAAA,CAAAA,EAAAA;MA7BA;IAiCA,MAAAhD,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA,EAAAA;kBAAAiD,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MADA,YAAAC,aAAAA,CAAAA,CAAAA,KAAAA,CACAA;MAjCA;IAkCA,MAAAlD,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAmD,YAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MAlCA;IAmCA,MAAAnD,SAAAA,CAAAA,YAAAA,GAAAA,UAAAA,KAAAA;kBAAAoD,kBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAnCA;IAoCA,MAAApD,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAqD,aAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MApCA;IAqCA,MAAArD,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;kBAAAsD,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MArCA;IAsCA,MAAAtD,SAAAA,CAAAA,eAAAA,GAAAA,UAAAA,KAAAA;kBAAAuD,qBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAtCA;IAuCA,MAAAvD,SAAAA,CAAAA,YAAAA,GAAAA,UAAAA,KAAAA;kBAAAwD,kBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAvCA;IAwCA,MAAAxD,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAyD,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAxCA;IAyCA,MAAAzD,SAAAA,CAAAA,eAAAA,GAAAA,UAAAA,KAAAA;kBAAA0D,qBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAzCA;IA0CA,MAAA1D,SAAAA,CAAAA,cAAAA,GAAAA,UAAAA,KAAAA;kBAAA2D,oBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA1CA;IA2CA,MAAA3D,SAAAA,CAAAA,wBAAAA,GAAAA,UAAAA,KAAAA;kBAAA4D,8BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA3CA;IA4CA,MAAA5D,SAAAA,CAAAA,uBAAAA,GAAAA,UAAAA,KAAAA;kBAAA6D,6BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA5CA;IA6CA,MAAA7D,SAAAA,CAAAA,qBAAAA,GAAAA,UAAAA,KAAAA;kBAAA8D,2BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA7CA;IA8CA,MAAA9D,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA;kBAAA+D,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9CA;IA+CA,MAAA/D,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAgE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA/CA;IAgDA,MAAAhE,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAiE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAhDA;IAiDA,MAAAjE,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAkE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAjDA;IAkDA,MAAAlE,SAAAA,CAAAA,oBAAAA,GAAAA,UAAAA,KAAAA;kBAAAmE,0BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAlDA;IAoDA,MAAAnE,SAAAA,CAAAA,iBAAAA,GAAAA,UAAAA,KAAAA;kBAAAoE,uBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MApDA;IAuDA,MAAApE,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAqE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAvDA;IAwDA,MAAArE,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAsE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAxDA;IAyDA,MAAAtE,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAuE,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAzDA;IA0DA,MAAAvE,SAAAA,CAAAA,eAAAA,GAAAA,UAAAA,KAAAA;kBAAAwE,qBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA1DA;IA6DA,MAAAxE,SAAAA,CAAAA,YAAAA,GAAAA,UAAAA,KAAAA;kBAAAyE,kBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA7DA;IA+DA,MAAAzE,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAyJ,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MA/DA;;;MAUW,YAAAtJ,UAAAA,CAAAA,EAVXA;;;;;;;;EAUChB,CAAAA,CAAAA,cAAAA,CAAAA,qBAAAA,EAAAA,sBAAAA,CAVDA;GAAAA,mBAAAA,C;;ACAM,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,iBAAAA,EAAAA,WAAAA,EAAAA;aAAAuK,KAAAA,GAAAA;MAAAvK,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAmC,KAAAwK,YAAAA,GAAAA,IAAnCA;MACU,KAAAC,aAAAA,GAAAA,IADVA;;IAAAF,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAmCA,CAAAA,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAC,YAAAA;MAAnC;IAAAD,KACUA,CAAAA,SAAAA,CAAAA,0BAAAA,CAAAA,GAAAA;kBAAAE,aAAAA;MADV;IAAAF,KAGGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA,YAE6BA;MADvC,IAAI,IAAW,CAAAG,gBAAAA,CAAAA,EAAfA;QAAmB,IAAnB,KAAmB,eAAnB;;QACG,IAAI,IAAW,CAAAC,gBAAAA,CAAAA,EAAfA;UAAmB,IADtB,KACsB,KAAnB;;UAA2B,IAD9B,KAC8B,WAA3B;SADH;OACuC;MAAQ,YAAP,IAAO,CAAAC,YAAAA,CAAAA,EAARA;cADvC,KACuC,GAAQ,KAAR;KAF7B,CAHH;IAAAL,KAQNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAAWA,OAAXA;MACY,OAAd,KAAAM,yBAAAA,CAAAA,EAAcA,CAAdA,UAAcA,CAACA,OAADA,EAA2BA,IAAAA,CAAAA,0BAAAA,CAAAA,EAAAA,CAAAA,IAA3BA,CADZA;MARM;IAAAN,KAWNA,CAAAA,SAAAA,CAAAA,sCAAAA,CAAAA,GAAAA,UAAiBA,QAAjBA;MACF,SAAE,EAACO,QAAKA,CAAAA,0BAAAA,CAAAA,EAAAA,CAAAA,SAA4BA,CAACA,IAAKA,CAAAA,0BAAAA,CAAAA,EAAAA,CAAAA,IAANA,CAAlCA,CAAFA,CADEA;MAXM;IAAAP,KAcNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MACF,YAAAQ,0BAAAA,CAAAA,EAAAA,CAAAA,WADEA;MAdM;IAAAR,KAiBNA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA;MACF,YAAAQ,0BAAAA,CAAAA,EAAAA,CAAAA,OADEA;MAjBM;IAAAR,KAoBNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MACF,YAAAQ,0BAAAA,CAAAA,EAAAA,CAAAA,WADEA;MApBM;IAAAR,KAuBNA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA;MACF,YAAAQ,0BAAAA,CAAAA,EAAAA,CAAAA,WADEA;MAvBM;IAAAR,KA2BNA,CAAAA,SAAAA,CAAAA,kCAAAA,CAAAA,GAAAA;MACF,IAAI,EAAC,KAAAQ,0BAAAA,CAAAA,EAAAA,CAAAA,UAADA,CAAJA;QAAsB,WAAtB;;QACqC,OAAA/K,CAAAA,CAAAA,UAAAA,CAAhCA,IAAAA,CAAAA,0BAAAA,CAAAA,EAAAA,CAAAA,UAAAA,CAAAA,GAAgCA,EAAAA,iBAAAA,CADrCA;OADE;MA3BM;IAAAuK,KA+BNA,CAAAA,SAAAA,CAAAA,qCAAAA,CAAAA,GAAAA;MACF,IAAI,IAAO,CAAAS,YAAAA,CAAAA,EAAXA;QAAkD,OAAAhL,CAAAA,CAAAA,UAAAA,CAAnCA,IAAAA,CAAAA,0BAAAA,CAAAA,EAAAA,CAAAA,aAAAA,CAAAA,GAAmCA,EAAAA,iBAAAA,CAAlDA;;QACK,WADL;OADE;MA/BM;IAAAuK,KAASA,CAAAA,SAAAA,CAAAA,8CAAAA,CAAAA,GAAAA,UAA0BA,OAA1BA,EACCA,QADDA,EAAAA;MAA0B,KAAAC,YAAAA,UAA1BA;MACC,KAAAC,aAAAA,WADDA;MAAAzK,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAAT;IAAAuK,KAQNA,CAAAA,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA;kBAAAU,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MARM;IAAAV,KAWNA,CAAAA,SAAAA,CAAAA,gBAAAA,GAAAA,UAAAA,KAAAA;kBAAAW,sCAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAXM;IAAAX,KAcNA,CAAAA,SAAAA,CAAAA,WAAAA,GAAAA;kBAAAG,gBAAAA,CAAAA,EAAAA;MAdM;IAAAH,KAiBNA,CAAAA,SAAAA,CAAAA,OAAAA,GAAAA;kBAAAS,YAAAA,CAAAA,EAAAA;MAjBM;IAAAT,KAoBNA,CAAAA,SAAAA,CAAAA,WAAAA,GAAAA;kBAAAI,gBAAAA,CAAAA,EAAAA;MApBM;IAAAJ,KAuBNA,CAAAA,SAAAA,CAAAA,OAAAA,GAAAA;kBAAAK,YAAAA,CAAAA,EAAAA;MAvBM;IAAAL,KA2BNA,CAAAA,SAAAA,CAAAA,aAAAA,GAAAA;kBAAAY,kCAAAA,CAAAA,EAAAA;MA3BM;IAAAZ,KA+BNA,CAAAA,SAAAA,CAAAA,gBAAAA,GAAAA;kBAAAa,qCAAAA,CAAAA,EAAAA;MA/BM;IAAAb,OAAAA,GAAAA,SAAAA;IAAAvK,CAAAA,CAAAA,WAAAA,CAAAA,iBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAuK,iBAAAA,EAAAA,IAAAA;MAAArK,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AJsDN,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,8BAAAA,EAAAA,WAAAA,EAAAA;aAAAqL,KAAAA;MAAArL,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAqL,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAkBA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAACA,WAADA,EAAkBA,SAAlBA,EAAAA;MAAArL,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAA6DA,WAA7DA,EAAsEA,SAAtEA,CAAAA;;MAAlB;IAAAqL,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAAC,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,IAAXA,CAATA;;MADA;IAAAD,KAEAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,WAALA,EAAAA;MAAwB,KAAAC,gCAAAA,CAAAA,CAAKA,WAALA,EAAcA,IAAdA,CAAxBA;;MAFA;IAAAD,KAGAA,CAAAA,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,UAAKA,SAALA,EAAAA;MAAyB,KAAAC,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,SAAXA,CAAzBA;;MAHA;aAAAD,OAAAA,CAGAA,KAHAA,EAGAA,KAHAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAGA,QAAAxK,SAAAA,CAAAA,MAAAA;;UAFA,YAAAG,UAAAA,CAAAA,EAEAA;;UADA,YAAAF,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAA0D,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YACA,IAAAxE,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,qBAAAA,CAAAA;0BAAAuL,+BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;aADA;WACA;;UAHkB,YAAAD,gCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAGlBA;;;OAHA;;IAAAD,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAArL,CAAAA,CAAAA,WAAAA,CAAAA,8BAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,4BAAAA,EAAAA;MAAAqL,8BAAAA,EAAAA,IAAAA;MAAA3G,4BAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AAMA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,sCAAAA,EAAAA,WAAAA,EAAAA;aAAAwL,KAAAA;MAAAxL,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAwL,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAA0BA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAACA,KAADA,EAAAA;MAAAxL,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAA8BA,KAA9BA,CAAAA;;MAA1B;IAAAwL,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAAhH,WAAAA,CAAAA,CAAKA,IAALA,CAATA;;MADA;aAAAgH,OAAAA,CACAA,KADAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACA,QAAA3K,SAAAA,CAAAA,MAAAA;;sBAAAG,UAAAA,CAAAA,EAAAA;;UAD0B,YAAAwD,WAAAA,CAAAA,CAAAA,KAAAA,CAC1BA;;;OADA;;IAAAgH,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAxL,CAAAA,CAAAA,WAAAA,CAAAA,sCAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,qBAAAA,EAAAA;MAAAwL,sCAAAA,EAAAA,IAAAA;MAAA7G,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AE2JM,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,kBAAAA,EAAAA,WAAAA,EAAAA;aAAAyL,KAAAA,GAAAA;MAAAzL,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAmB,KAAAsF,cAAAA,GAAAA,GAAnBA;MACU,KAAAe,cAAAA,GAAAA,KADVA;;IAAAoF,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAmBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAnG,cAAAA;MAAnB;IAAAmG,KACUA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAApF,cAAAA;MADV;IAAAoF,KAGGA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAoB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAApBA;MAHH;IAAAD,KAIGA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAqB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAArBA;MAJH;IAAAD,KAKNA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAmB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAAnBA;MALM;IAAAD,KAMNA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAoB,OAAAzL,CAAAA,CAAAA,cAAAA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,CAApBA;MANM;IAAAyL,KAONA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAC,UAAAA,CAAAA,EAAfA;MAPM;IAAAD,KAQNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MAAgB,YAAAC,UAAAA,CAAAA,EAAhBA;MARM;IAAAD,KAUGA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACe,QAATzL,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,kBAAAA,CAASA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,kBAAAA,CAASA,CAAAA,UAAAA,CAAAA,EAA7BA,CAAVA,CADfA;MAVH;IAAAyL,KAaGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAA6B,OAAjB,KAAAC,UAAAA,CAAAA,EAAiBA,CAAAA,QAAAA,EAA7BA;MAbH;IAAAD,KAeNA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAmC,OAAZzL,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAYA,CAAAA,WAAAA,CAAAA,CAACA,IAAAA,CAAAA,UAAAA,CAAAA,EAADA,CAAnCA;MAfM;IAAAyL,KAAMA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAnG,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACI,KAAAqG,cAAAA,GAAQA,KADZA;;MAAN;IAAAoF,KAeNA,CAAAA,SAAAA,CAAAA,KAAAA,GAAAA;kBAAAE,UAAAA,CAAAA,EAAAA;MAfM;aAAAF,OAAAA,CAAMA,KAANA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAM,YAAAzG,WAAAA,CAAAA,CAAAA,KAAAA,CAANA;;IAAAyG,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAzL,CAAAA,CAAAA,WAAAA,CAAAA,kBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAyL,kBAAAA,EAAAA,IAAAA;MAAAjF,kBAAAA,EAAAA,IAAAA;MAAAtG,kBAAAA,EAAAA,IAAAA;;;;;;MAmBN,KAAAuF,aAAAA,GAAAA,IAnBMA;MAoBN,KAAAmG,0BAAAA,GAAAA,GApBMA;MAqBN,KAAAC,0BAAAA,GAAAA,GArBMA;MAsBN,KAAAC,YAAAA,GAAAA,GAtBMA;MAuBN,KAAApF,kBAAAA,GAAAA,GAvBMA;MAwBN,KAAAqF,mBAAAA,GAAAA,GAxBMA;MAyBN,KAAAtF,kBAAAA,GAAAA,GAzBMA;MA0BN,KAAAuF,qBAAAA,GAAAA,CA1BMA;MA2BN,KAAAC,qBAAAA,GAAAA,CA3BMA;MA4BN,KAAAC,aAAAA,GAAAA,CA5BMA;;;;IAmBN,MAAAtG,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAnBM;IAoBN,MAAAG,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA;kBAAAgG,0BAAAA;MApBM;IAqBN,MAAAhG,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA;kBAAAiG,0BAAAA;MArBM;IAsBN,MAAAjG,SAAAA,CAAAA,QAAAA,CAAAA,GAAAA;kBAAAkG,YAAAA;MAtBM;IAuBN,MAAAlG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAvBM;IAwBN,MAAAd,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;kBAAAmG,mBAAAA;MAxBM;IAyBN,MAAAnG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAzBM;IA0BN,MAAAb,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;kBAAAoG,qBAAAA;MA1BM;IA2BN,MAAApG,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;kBAAAqG,qBAAAA;MA3BM;IA4BN,MAAArG,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA;kBAAAsG,aAAAA;MA5BM;IA8BN,MAAAtG,SAAAA,CAAAA,8BAAAA,CAAAA,GAAAA,UAAQA,eAARA;MAAqC,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAWA,eAAXA,CAArCA;MA9BM;IA+BN,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAAuD,OAAhB5F,CAAAA,CAAAA,CAAAA,CAAAA,iBAAAA,CAAgBA,CAAAA,gBAAAA,CAAAA,CAACA,KAADA,CAAvDA;MA/BM;IAgCN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAqD,OAAzB5F,CAAAA,CAAAA,CAAAA,CAAAA,iBAAAA,CAAaA,CAAAA,6BAAAA,CAAAA,CAACA,KAADA,CAAYA,CAAAA,aAAAA,CAAAA,EAArDA;MAhCM;IAkCN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAAyBA,KAAzBA;MACF,IAAM,CAAFuG,KAAEA,KAAGA,KAAHA,CAANA;QAAY,QAAZ;;QACK,IAAM,CAAFA,KAAEA,GAAEA,KAAFA,CAANA;UAAY,SAAZ;;UACA,QADA;SADL;OADE;MAlCM;IAwCN,MAAAvG,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAiD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAjDA;MAxCM;IAyCN,MAAA4F,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAAWA,KAAXA;MAAsD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAtDA;MAzCM;IA2CN,MAAA4F,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA,UAAiBA,QAAjBA;MAA4D,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA5DA;MA3CM;IA4CN,MAAA4F,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA,UAAiBA,SAAjBA;MAA6D,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA7DA;MA5CM;IAkBE,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACR,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,cAAAA,CAAAA,CAAAA,GADNA;MAER,KAAAmG,0BAAAA,GAAoBA,GAFZA;MAGR,KAAAC,0BAAAA,GAAoBA,GAHZA;MAIR,KAAAC,YAAAA,GAAMA,GAJEA;MAKR,KAAApF,kBAAAA,GAAYA,GALJA;MAMR,KAAAqF,mBAAAA,GAAaA,GANLA;MAOR,KAAAtF,kBAAAA,GAAYA,GAPJA;MAQR,KAAAuF,qBAAAA,GAAeA,IARPA;MASR,KAAAC,qBAAAA,GAAgBA,KATRA;MAUR,KAAAC,aAAAA,GAAOA,EAVCA;;MAlBF;IAmBN,MAAAtG,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAnBM;IAoBN,MAAAL,SAAAA,CAAAA,iBAAAA,GAAAA;kBAAAwG,sBAAAA,CAAAA,EAAAA;MApBM;IAqBN,MAAAxG,SAAAA,CAAAA,iBAAAA,GAAAA;kBAAAyG,sBAAAA,CAAAA,EAAAA;MArBM;IAsBN,MAAAzG,SAAAA,CAAAA,GAAAA,GAAAA;kBAAA0G,QAAAA,CAAAA,EAAAA;MAtBM;IAuBN,MAAA1G,SAAAA,CAAAA,SAAAA,GAAAA;kBAAA2G,cAAAA,CAAAA,EAAAA;MAvBM;IAwBN,MAAA3G,SAAAA,CAAAA,UAAAA,GAAAA;kBAAA4G,eAAAA,CAAAA,EAAAA;MAxBM;IAyBN,MAAA5G,SAAAA,CAAAA,SAAAA,GAAAA;kBAAA6G,cAAAA,CAAAA,EAAAA;MAzBM;IA0BN,MAAA7G,SAAAA,CAAAA,YAAAA,GAAAA;kBAAA8G,iBAAAA,CAAAA,EAAAA;MA1BM;IA2BN,MAAA9G,SAAAA,CAAAA,YAAAA,GAAAA;kBAAA+G,iBAAAA,CAAAA,EAAAA;MA3BM;IA4BN,MAAA/G,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAgH,SAAAA,CAAAA,EAAAA;MA5BM;IA8BN,MAAAhH,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAiH,8BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9BM;IA+BN,MAAAjH,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAkH,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA/BM;IAgCN,MAAAlH,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAkM,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MAhCM;IAkCN,MAAAnH,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAoH,cAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MAlCM;IAwCN,MAAApH,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA;kBAAAqH,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAxCM;IAyCN,MAAArH,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA;kBAAAsH,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAzCM;IA2CN,MAAAtH,SAAAA,CAAAA,gBAAAA,GAAAA,UAAAA,KAAAA;kBAAAuH,sBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA3CM;IA4CN,MAAAvH,SAAAA,CAAAA,gBAAAA,GAAAA,UAAAA,KAAAA;kBAAAwH,sBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA5CM;;;MAkBE,YAAApM,UAAAA,CAAAA,EAlBFA;;;;;;;;EAkBLhB,CAAAA,CAAAA,cAAAA,CAAAA,kBAAAA,EAAAA,mBAAAA,CAlBKA;GAAAA,mBAAAA,C;;AFzMN,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,iBAAAA,EAAAA,WAAAA,EAAAA;aAAAqN,KAAAA;MAAArN,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAqN,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAKA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAACA,WAADA,EAAkBA,SAAlBA,EAAAA;MAAArN,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAAsDA,WAAtDA,EAA+DA,SAA/DA,CAAAA;;MAAL;IAAAqN,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAA/B,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,IAAXA,CAATA;;MADA;IAAA+B,KAEAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,WAALA,EAAAA;MAAwB,KAAA/B,gCAAAA,CAAAA,CAAKA,WAALA,EAAcA,IAAdA,CAAxBA;;MAFA;IAAA+B,KAGAA,CAAAA,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,UAAKA,SAALA,EAAAA;MAAyB,KAAA/B,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,SAAXA,CAAzBA;;MAHA;aAAA+B,OAAAA,CAGAA,KAHAA,EAGAA,KAHAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAGA,QAAAxM,SAAAA,CAAAA,MAAAA;;UAFA,YAAAG,UAAAA,CAAAA,EAEAA;;UADA,YAAAF,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAA0D,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YACA,IAAAxE,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,qBAAAA,CAAAA;0BAAAuL,+BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;aADA;WACA;;UAHK,YAAAD,gCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAGLA;;;OAHA;;IAAA+B,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAArN,CAAAA,CAAAA,WAAAA,CAAAA,iBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,qBAAAA,EAAAA;MAAAqN,iBAAAA,EAAAA,IAAAA;MAAAzI,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AAgBA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,qBAAAA,EAAAA,WAAAA,EAAAA;aAAA2E,KAAAA;MAAA3E,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAA2E,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAASA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,GAAAA,UAACA,WAADA,EAAkBA,SAAlBA,EAAAA;MAAA3E,CAAAA,CAAAA,CAAAA,CAAAA,qBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,gCAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAAsDA,WAAtDA,EAA+DA,SAA/DA,CAAAA;;MAAT;IAAA2E,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAA2G,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,IAAXA,CAATA;;MADA;IAAA3G,KAEAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAKA,WAALA,EAAAA;MAAwB,KAAA2G,gCAAAA,CAAAA,CAAKA,WAALA,EAAcA,IAAdA,CAAxBA;;MAFA;IAAA3G,KAGAA,CAAAA,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,UAAKA,SAALA,EAAAA;MAAyB,KAAA2G,gCAAAA,CAAAA,CAAKA,IAALA,EAAWA,SAAXA,CAAzBA;;MAHA;aAAA3G,OAAAA,CAGAA,KAHAA,EAGAA,KAHAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAGA,QAAA9D,SAAAA,CAAAA,MAAAA;;UAFA,YAAAG,UAAAA,CAAAA,EAEAA;;UADA,YAAAF,KAAAA,CAAAA,KAAAA,QAAAA,CAAAA;wBAAA0D,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;YACA,IAAAxE,CAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,qBAAAA,CAAAA;0BAAAuL,+BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;aADA;WACA;;UAHS,YAAAD,gCAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAGTA;;;OAHA;;IAAA3G,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAA3E,CAAAA,CAAAA,WAAAA,CAAAA,qBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,qBAAAA,EAAAA;MAAA2E,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AEqIM,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,iBAAAA,EAAAA,WAAAA,EAAAA;aAAAsN,KAAAA,GAAAA;MAAAtN,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAkB,KAAAsF,cAAAA,GAAAA,GAAlBA;MACU,KAAAe,cAAAA,GAAAA,KADVA;;IAAAiH,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAkBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAhI,cAAAA;MAAlB;IAAAgI,KACUA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAjH,cAAAA;MADV;IAAAiH,KAGGA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAoB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAApBA;MAHH;IAAAD,KAIGA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAqB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAArBA;MAJH;IAAAD,KAKNA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAmB,QAAN,KAAAC,UAAAA,CAAAA,EAAMA,GAAAA,CAAAA,CAAnBA;MALM;IAAAD,KAMNA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAoB,OAAAtN,CAAAA,CAAAA,cAAAA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,CAApBA;MANM;IAAAsN,KAONA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAC,UAAAA,CAAAA,EAAfA;MAPM;IAAAD,KAQNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MAAgB,YAAAC,UAAAA,CAAAA,EAAhBA;MARM;IAAAD,KAUGA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACc,QAARtN,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,iBAAAA,CAAQA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,iBAAAA,CAAQA,CAAAA,UAAAA,CAAAA,EAA5BA,CAAVA,CADdA;MAVH;IAAAsN,KAaGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAA6B,OAAjB,KAAAC,UAAAA,CAAAA,EAAiBA,CAAAA,QAAAA,EAA7BA;MAbH;IAAAD,KAeNA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;MAAkC,OAAXtN,CAAAA,CAAAA,CAAAA,CAAAA,iBAAAA,CAAWA,CAAAA,WAAAA,CAAAA,CAACA,IAAAA,CAAAA,UAAAA,CAAAA,EAADA,CAAlCA;MAfM;IAAAsN,KAAKA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAhI,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACK,KAAAqG,cAAAA,GAAQA,KADbA;;MAAL;IAAAiH,KAeNA,CAAAA,SAAAA,CAAAA,KAAAA,GAAAA;kBAAA3B,UAAAA,CAAAA,EAAAA;MAfM;aAAA2B,OAAAA,CAAKA,KAALA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAK,YAAArI,WAAAA,CAAAA,CAAAA,KAAAA,CAALA;;IAAAqI,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAtN,CAAAA,CAAAA,WAAAA,CAAAA,iBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAsN,iBAAAA,EAAAA,IAAAA;MAAA9G,kBAAAA,EAAAA,IAAAA;MAAAtG,kBAAAA,EAAAA,IAAAA;;;;;;MAmBN,KAAAuF,aAAAA,GAAAA,IAnBMA;MAoBN,KAAAmG,0BAAAA,GAAAA,GApBMA;MAqBN,KAAAC,0BAAAA,GAAAA,GArBMA;MAsBN,KAAAC,YAAAA,GAAAA,GAtBMA;MAuBN,KAAApF,kBAAAA,GAAAA,GAvBMA;MAwBN,KAAAqF,mBAAAA,GAAAA,GAxBMA;MAyBN,KAAAtF,kBAAAA,GAAAA,GAzBMA;MA0BN,KAAAuF,qBAAAA,GAAAA,CA1BMA;MA2BN,KAAAC,qBAAAA,GAAAA,CA3BMA;MA4BN,KAAAC,aAAAA,GAAAA,CA5BMA;;;;IAmBN,MAAAtG,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAnBM;IAoBN,MAAAG,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA;kBAAAgG,0BAAAA;MApBM;IAqBN,MAAAhG,SAAAA,CAAAA,sBAAAA,CAAAA,GAAAA;kBAAAiG,0BAAAA;MArBM;IAsBN,MAAAjG,SAAAA,CAAAA,QAAAA,CAAAA,GAAAA;kBAAAkG,YAAAA;MAtBM;IAuBN,MAAAlG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAvBM;IAwBN,MAAAd,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;kBAAAmG,mBAAAA;MAxBM;IAyBN,MAAAnG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAzBM;IA0BN,MAAAb,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;kBAAAoG,qBAAAA;MA1BM;IA2BN,MAAApG,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA;kBAAAqG,qBAAAA;MA3BM;IA4BN,MAAArG,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA;kBAAAsG,aAAAA;MA5BM;IA8BN,MAAAtG,SAAAA,CAAAA,6BAAAA,CAAAA,GAAAA,UAAQA,cAARA;MAAmC,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,iBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAUA,cAAVA,CAAnCA;MA9BM;IAgCN,MAAA4F,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAAWA,KAAXA;MACW,OAAV5F,CAAAA,CAAAA,CAAUA,CAAAA,UAAAA,CAACA,KAADA,CADXA;MAhCM;IAmCN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAsC,OAAX,IAAO,CAAA4H,6BAAAA,CAAAA,CAACA,KAADA,CAAIA,CAAAA,aAAAA,CAAAA,EAAtCA;MAnCM;IAqCN,MAAA5H,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAAQA,KAARA,EAAwBA,KAAxBA;MACF,IAAM,CAAFuG,KAAEA,KAAGA,KAAHA,CAANA;QAAY,QAAZ;;QACK,IAAM,CAAFA,KAAEA,GAAEA,KAAFA,CAANA;UAAY,SAAZ;;UACA,QADA;SADL;OADE;MArCM;IA2CN,MAAAvG,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAgD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAhDA;MA3CM;IA4CN,MAAA4F,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA,UAAWA,KAAXA;MAAqD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArDA;MA5CM;IA8CN,MAAA4F,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,UAAeA,QAAfA;MAAwD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAxDA;MA9CM;IA+CN,MAAA4F,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,UAAeA,SAAfA;MAAyD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAzDA;MA/CM;IAkBC,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,iBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACP,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,aAAAA,CAAAA,CAAAA,GADPA;MAEP,KAAAmG,0BAAAA,GAAoBA,GAFbA;MAGP,KAAAC,0BAAAA,GAAoBA,GAHbA;MAIP,KAAAC,YAAAA,GAAMA,GAJCA;MAKP,KAAApF,kBAAAA,GAAYA,GALLA;MAMP,KAAAqF,mBAAAA,GAAaA,GANNA;MAOP,KAAAtF,kBAAAA,GAAYA,GAPLA;MAQP,KAAAuF,qBAAAA,GAAeA,GARRA;MASP,KAAAC,qBAAAA,GAAgBA,IATTA;MAUP,KAAAC,aAAAA,GAAOA,EAVAA;;MAlBD;IAmBN,MAAAtG,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAnBM;IAoBN,MAAAL,SAAAA,CAAAA,iBAAAA,GAAAA;kBAAA6H,sBAAAA,CAAAA,EAAAA;MApBM;IAqBN,MAAA7H,SAAAA,CAAAA,iBAAAA,GAAAA;kBAAA8H,sBAAAA,CAAAA,EAAAA;MArBM;IAsBN,MAAA9H,SAAAA,CAAAA,GAAAA,GAAAA;kBAAA+H,QAAAA,CAAAA,EAAAA;MAtBM;IAuBN,MAAA/H,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAgI,cAAAA,CAAAA,EAAAA;MAvBM;IAwBN,MAAAhI,SAAAA,CAAAA,UAAAA,GAAAA;kBAAAiI,eAAAA,CAAAA,EAAAA;MAxBM;IAyBN,MAAAjI,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAkI,cAAAA,CAAAA,EAAAA;MAzBM;IA0BN,MAAAlI,SAAAA,CAAAA,YAAAA,GAAAA;kBAAA8G,iBAAAA,CAAAA,EAAAA;MA1BM;IA2BN,MAAA9G,SAAAA,CAAAA,YAAAA,GAAAA;kBAAA+G,iBAAAA,CAAAA,EAAAA;MA3BM;IA4BN,MAAA/G,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAgH,SAAAA,CAAAA,EAAAA;MA5BM;IA8BN,MAAAhH,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAA4H,6BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9BM;IAgCN,MAAA5H,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA;kBAAAmI,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAhCM;IAmCN,MAAAnI,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAmN,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MAnCM;IAqCN,MAAApI,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAqI,cAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MArCM;IA2CN,MAAArI,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA;kBAAAsI,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA3CM;IA4CN,MAAAtI,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA;kBAAAuI,gBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA5CM;IA8CN,MAAAvI,SAAAA,CAAAA,cAAAA,GAAAA,UAAAA,KAAAA;kBAAAwI,oBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9CM;IA+CN,MAAAxI,SAAAA,CAAAA,cAAAA,GAAAA,UAAAA,KAAAA;kBAAAyI,oBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA/CM;;;MAkBC,YAAArN,UAAAA,CAAAA,EAlBDA;;;;;;;;EAkBLhB,CAAAA,CAAAA,cAAAA,CAAAA,iBAAAA,EAAAA,kBAAAA,CAlBKA;GAAAA,mBAAAA,C;;AFnFN,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,oCAAAA,EAAAA,WAAAA,EAAAA;aAAAsO,KAAAA;MAAAtO,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAsO,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAwBA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAACA,WAADA,EAAAA;MAAAtO,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAA2CA,WAA3CA,CAAAA;;MAAxB;IAAAsO,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAA9J,WAAAA,CAAAA,CAAKA,IAALA,CAATA;;MADA;aAAA8J,OAAAA,CACAA,KADAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACA,QAAAzN,SAAAA,CAAAA,MAAAA;;sBAAAG,UAAAA,CAAAA,EAAAA;;UADwB,YAAAwD,WAAAA,CAAAA,CAAAA,KAAAA,CACxBA;;;OADA;;IAAA8J,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAtO,CAAAA,CAAAA,WAAAA,CAAAA,oCAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,4BAAAA,EAAAA;MAAAsO,oCAAAA,EAAAA,IAAAA;MAAA5J,4BAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AAhBA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,qCAAAA,EAAAA,WAAAA,EAAAA;aAAAyE,KAAAA;MAAAzE,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAyE,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAyBA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAACA,KAADA,EAAAA;MAAAzE,CAAAA,CAAAA,CAAAA,CAAAA,4BAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,EAAqCA,KAArCA,CAAAA;;MAAzB;IAAAyE,KACAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAS,KAAAD,WAAAA,CAAAA,CAAKA,IAALA,CAATA;;MADA;aAAAC,OAAAA,CACAA,KADAA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACA,QAAA5D,SAAAA,CAAAA,MAAAA;;sBAAAG,UAAAA,CAAAA,EAAAA;;UADyB,YAAAwD,WAAAA,CAAAA,CAAAA,KAAAA,CACzBA;;;OADA;;IAAAC,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAzE,CAAAA,CAAAA,WAAAA,CAAAA,qCAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,4BAAAA,EAAAA;MAAAyE,qCAAAA,EAAAA,IAAAA;MAAAC,4BAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAAC,qBAAAA,EAAAA,IAAAA;MAAA1E,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AKlEA,UAAAA,CAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,kCAAAA,EAAAA,WAAAA,EAAAA;aAAAuO,KAAAA;MAAAvO,CAAAA,CAAAA,CAAAA,CAAAA,uBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;IAAAuO,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,uBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAA0BA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAAvO,CAAAA,CAAAA,CAAAA,CAAAA,uBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;;MAA1B;aAAAuO,OAAAA,GAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAA0B,YAAAvN,UAAAA,CAAAA,EAA1BA;;IAAAuN,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAvO,CAAAA,CAAAA,WAAAA,CAAAA,kCAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,uBAAAA,EAAAA;MAAAuO,kCAAAA,EAAAA,IAAAA;MAAAC,uBAAAA,EAAAA,IAAAA;MAAAtO,kBAAAA,EAAAA,IAAAA;;;GAAAF,mBAAAA,C;;AHuFM,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,mBAAAA,EAAAA,WAAAA,EAAAA;aAAAyO,KAAAA,GAAAA;MAAAzO,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAoB,KAAAsF,cAAAA,GAAAA,CAApBA;MACU,KAAAe,cAAAA,GAAAA,KADVA;;IAAAoI,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAoBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAnJ,cAAAA;MAApB;IAAAmJ,KACUA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAApI,cAAAA;MADV;IAAAoI,KAGNA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAa,YAAAC,UAAAA,CAAAA,EAAbA;MAHM;IAAAD,KAINA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAc,YAAAC,UAAAA,CAAAA,EAAdA;MAJM;IAAAD,KAKNA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAC,UAAAA,CAAAA,EAAfA;MALM;IAAAD,KAMNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MAAgB,YAAAC,UAAAA,CAAAA,EAAhBA;MANM;IAAAD,KAQGA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACgB,QAAVzO,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,mBAAAA,CAAUA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,mBAAAA,CAAUA,CAAAA,UAAAA,CAAAA,EAA9BA,CAAVA,CADhBA;MARH;IAAAyO,KAWGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAA6B,OAAjB,KAAAC,UAAAA,CAAAA,EAAiBA,CAAAA,QAAAA,EAA7BA;MAXH;IAAAD,KAAOA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAnJ,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACG,KAAAqG,cAAAA,GAAQA,IADXA;;MAAP;aAAAoI,OAAAA,CAAOA,KAAPA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAO,YAAAvJ,WAAAA,CAAAA,CAAAA,KAAAA,CAAPA;;IAAAuJ,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAzO,CAAAA,CAAAA,WAAAA,CAAAA,mBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAyO,mBAAAA,EAAAA,IAAAA;MAAAjI,kBAAAA,EAAAA,IAAAA;MAAAtG,kBAAAA,EAAAA,IAAAA;;;;;;MAeN,KAAAuF,aAAAA,GAAAA,IAfMA;MAgBN,KAAAgB,kBAAAA,GAAAA,CAhBMA;MAiBN,KAAAC,kBAAAA,GAAAA,CAjBMA;;;;IAeN,MAAAd,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAfM;IAgBN,MAAAG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAhBM;IAiBN,MAAAb,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAjBM;IAmBN,MAAAd,SAAAA,CAAAA,+BAAAA,CAAAA,GAAAA,UAAQA,YAARA;MAA+B,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAAYA,YAAZA,CAA/BA;MAnBM;IAqBN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MACa,QAAZ5F,CAAAA,CAAAA,CAAQA,CAAAA,QAAAA,CAACA,KAADA,CAAIA,GAAAA,CAAAA,CADbA;MArBM;IAwBN,MAAA4F,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA,UAASA,KAATA,EAAoBA,SAApBA;MACoB,QAAnB5F,CAAAA,CAAAA,CAAQA,CAAAA,QAAAA,CAACA,KAADA,EAAIA,SAAJA,CAAWA,GAAAA,CAAAA,CADpBA;MAxBM;IA2BN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAoC,OAAX,IAAO,CAAA+I,+BAAAA,CAAAA,CAACA,KAADA,CAAIA,CAAAA,aAAAA,CAAAA,EAApCA;MA3BM;IA6BN,MAAA/I,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAA6C,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA7CA;MA7BM;IA8BN,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAaA,KAAbA;MAAiD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAjDA;MA9BM;IA+BN,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAWA,KAAXA,EAAyBA,YAAzBA;MAAoE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAApEA;MA/BM;IAgCN,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAYA,KAAZA,EAA0BA,YAA1BA;MAAqE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAArEA;MAhCM;IAkCN,MAAA4F,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,UAAeA,KAAfA;MAA6D,OAArBgJ,KAAqBA,CAAAA,QAAAA,CAACA,CAADA,CAA7DA;MAlCM;IAmCN,MAAAhJ,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAA0D,OAArBgJ,KAAqBA,CAAAA,QAAAA,CAACA,EAADA,CAA1DA;MAnCM;IAoCN,MAAAhJ,SAAAA,CAAAA,mBAAAA,CAAAA,GAAAA,UAAcA,KAAdA;MAA4D,OAArBgJ,KAAqBA,CAAAA,QAAAA,CAACA,CAADA,CAA5DA;MApCM;IAcG,MAAAhJ,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,mBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACT,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,WAAAA,CAAAA,CAAAA,GADLA;MAET,KAAAgB,kBAAAA,GAAwBA,WAFfA;MAGT,KAAAC,kBAAAA,GAAuBA,UAHdA;;MAdH;IAeN,MAAAd,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAfM;IAgBN,MAAAL,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAiJ,cAAAA,CAAAA,EAAAA;MAhBM;IAiBN,MAAAjJ,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAkJ,cAAAA,CAAAA,EAAAA;MAjBM;IAmBN,MAAAlJ,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAA+I,+BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAnBM;IAwBN,MAAA/I,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;UAHA,YAAAkO,cAAAA,CAAAA,CAAAA,KAAAA,CAGAA;;sBAAAC,eAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;;;;MAxBM;IA2BN,MAAApJ,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAoO,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MA3BM;IA6BN,MAAArJ,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;kBAAAsJ,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA7BM;IA8BN,MAAAtJ,SAAAA,CAAAA,YAAAA,GAAAA,UAAAA,KAAAA;kBAAAuJ,kBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9BM;IA+BN,MAAAvJ,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAwJ,iBAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MA/BM;IAgCN,MAAAxJ,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAyJ,kBAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MAhCM;IAkCN,MAAAzJ,SAAAA,CAAAA,cAAAA,GAAAA,UAAAA,KAAAA;kBAAA0J,oBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAlCM;IAmCN,MAAA1J,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAA2J,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAnCM;IAoCN,MAAA3J,SAAAA,CAAAA,aAAAA,GAAAA,UAAAA,KAAAA;kBAAA4J,mBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MApCM;;;MAcG,YAAAxO,UAAAA,CAAAA,EAdHA;;;;;;;;EAcLhB,CAAAA,CAAAA,cAAAA,CAAAA,mBAAAA,EAAAA,oBAAAA,CAdKA;GAAAA,mBAAAA,C;;AAyCA,UAAAA,CAAAA,EAAAA;EAAAA,CAAAA,CAAAA,aAAAA,CAAAA,gBAAAA,EAAAA,WAAAA,EAAAA;aAAAyP,KAAAA,GAAAA;MAAAzP,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAiB,KAAAsF,cAAAA,GAAAA,CAAjBA;MACU,KAAAe,cAAAA,GAAAA,KADVA;;IAAAoJ,KAAAA,CAAAA,SAAAA,GAAAA,MAAAA,CAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA;IAAAA,KAAAA,CAAAA,SAAAA,CAAAA,WAAAA,QAAAA;IAAAA,KAAiBA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAAnK,cAAAA;MAAjB;IAAAmK,KACUA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA;kBAAApJ,cAAAA;MADV;IAAAoJ,KAGGA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAc,YAAAC,UAAAA,CAAAA,EAAdA;MAHH;IAAAD,KAIGA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAC,UAAAA,CAAAA,EAAfA;MAJH;IAAAD,KAKNA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAAa,YAAAC,UAAAA,CAAAA,EAAbA;MALM;IAAAD,KAMNA,CAAAA,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;MAAc,YAAAC,UAAAA,CAAAA,EAAdA;MANM;IAAAD,KAONA,CAAAA,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA;MAAe,YAAAC,UAAAA,CAAAA,EAAfA;MAPM;IAAAD,KAQNA,CAAAA,SAAAA,CAAAA,gBAAAA,CAAAA,GAAAA;MAAgB,YAAAC,UAAAA,CAAAA,EAAhBA;MARM;IAAAD,KAUGA,CAAAA,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAOA,QAAPA;MACa,QAAPzP,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,gBAAAA,CAAOA,IAAUA,CAANA,IAAAA,CAAAA,UAAAA,CAAAA,EAAMA,KAAoBA,CAAAA,CAAAA,UAAAA,CAAjBA,QAAiBA,EAAAA,gBAAAA,CAAOA,CAAAA,UAAAA,CAAAA,EAA3BA,CAAVA,CADbA;MAVH;IAAAyP,KAaGA,CAAAA,SAAAA,CAAAA,aAAAA,CAAAA,GAAAA;MAA6B,OAAjB,KAAAC,UAAAA,CAAAA,EAAiBA,CAAAA,QAAAA,EAA7BA;MAbH;IAAAD,KAAIA,CAAAA,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAaA,SAAbA,EAAAA;MAAa,KAAAnK,cAAAA,YAAbA;MAAAtF,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MACM,KAAAqG,cAAAA,GAAQA,IADdA;;MAAJ;aAAAoJ,OAAAA,CAAIA,KAAJA,EAAAA;MAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAI,YAAAtK,WAAAA,CAAAA,CAAAA,KAAAA,CAAJA;;IAAAsK,OAAAA,CAAAA,SAAAA,GAAAA,KAAAA,CAAAA,SAAAA;IAAAzP,CAAAA,CAAAA,WAAAA,CAAAA,gBAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,kBAAAA,EAAAA;MAAAyP,gBAAAA,EAAAA,IAAAA;MAAAjJ,kBAAAA,EAAAA,IAAAA;MAAAtG,kBAAAA,EAAAA,IAAAA;;;;;;MAiBN,KAAAuF,aAAAA,GAAAA,IAjBMA;MAkBN,KAAAgB,kBAAAA,GAAAA,CAlBMA;MAmBN,KAAAC,kBAAAA,GAAAA,CAnBMA;;;;IAiBN,MAAAd,SAAAA,CAAAA,yBAAAA,CAAAA,GAAAA;kBAAAH,aAAAA;MAjBM;IAkBN,MAAAG,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAa,kBAAAA;MAlBM;IAmBN,MAAAb,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA;kBAAAc,kBAAAA;MAnBM;IAqBN,MAAAd,SAAAA,CAAAA,4BAAAA,CAAAA,GAAAA,UAAQA,aAARA;MAAiC,WAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,gBAAAA,CAAAA,EAAAA,CAAAA,WAAAA,CAAAA,CAASA,aAATA,CAAjCA;MArBM;IAsBN,MAAA4F,SAAAA,CAAAA,eAAAA,CAAAA,GAAAA,UAAUA,KAAVA;MAAmD,OAAhB5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAgBA,CAAAA,cAAAA,CAAAA,CAACA,KAADA,CAAnDA;MAtBM;IAuBN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAAmD,OAAzB5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAeA,CAAAA,+BAAAA,CAAAA,CAACA,KAADA,CAAUA,CAAAA,aAAAA,CAAAA,EAAnDA;MAvBM;IAyBN,MAAA4F,SAAAA,CAAAA,cAAAA,CAAAA,GAAAA,UAASA,KAATA;MAA+C,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA/CA;MAzBM;IA0BN,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAaA,KAAbA;MAAmD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAnDA;MA1BM;IA2BN,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAWA,KAAXA,EAA0BA,YAA1BA;MAAsE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAtEA;MA3BM;IA4BN,MAAA4F,SAAAA,CAAAA,kBAAAA,CAAAA,GAAAA,UAAYA,KAAZA,EAA2BA,YAA3BA;MAAuE,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAvEA;MA5BM;IA8BN,MAAA4F,SAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,UAAeA,KAAfA;MAAiD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAjDA;MA9BM;IA+BN,MAAA4F,SAAAA,CAAAA,iBAAAA,CAAAA,GAAAA,UAAYA,KAAZA;MAA8C,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAA9CA;MA/BM;IAgCN,MAAA4F,SAAAA,CAAAA,mBAAAA,CAAAA,GAAAA,UAAcA,KAAdA;MAAgD,OAAL5F,CAAAA,CAAAA,CAAAA,CAAAA,mBAAAA,CAAKA,CAAAA,yBAAAA,CAAAA,CAACA,eAADA,CAAhDA;MAhCM;IAgBA,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,gBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MACN,KAAAyF,aAAAA,GAAcA,CAAAA,CAAAA,UAAAA,CAAAA,YAAAA,CAAAA,CAAAA,GADRA;MAEN,KAAAgB,kBAAAA,GAAyBA,oBAFnBA;MAGN,KAAAC,kBAAAA,GAAwBA,mBAHlBA;;MAhBA;IAiBN,MAAAd,SAAAA,CAAAA,IAAAA,GAAAA;kBAAAK,yBAAAA,CAAAA,EAAAA;MAjBM;IAkBN,MAAAL,SAAAA,CAAAA,SAAAA,GAAAA;kBAAA+J,cAAAA,CAAAA,EAAAA;MAlBM;IAmBN,MAAA/J,SAAAA,CAAAA,SAAAA,GAAAA;kBAAAgK,cAAAA,CAAAA,EAAAA;MAnBM;IAqBN,MAAAhK,SAAAA,CAAAA,OAAAA,GAAAA,UAAAA,KAAAA;kBAAAiK,4BAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MArBM;IAsBN,MAAAjK,SAAAA,CAAAA,SAAAA,GAAAA,UAAAA,KAAAA;kBAAAkK,eAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAtBM;IAuBN,MAAAlK,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;cAAA/E,SAAAA,CAAAA,MAAAA;;;;sBAAAkP,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;;;;MAvBM;IAyBN,MAAAnK,SAAAA,CAAAA,QAAAA,GAAAA,UAAAA,KAAAA;kBAAAoK,cAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAzBM;IA0BN,MAAApK,SAAAA,CAAAA,YAAAA,GAAAA,UAAAA,KAAAA;kBAAAqK,kBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA1BM;IA2BN,MAAArK,SAAAA,CAAAA,UAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAsK,iBAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MA3BM;IA4BN,MAAAtK,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAuK,kBAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MA5BM;IA8BN,MAAAvK,SAAAA,CAAAA,cAAAA,GAAAA,UAAAA,KAAAA;kBAAAwK,oBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA9BM;IA+BN,MAAAxK,SAAAA,CAAAA,WAAAA,GAAAA,UAAAA,KAAAA;kBAAAyK,iBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA/BM;IAgCN,MAAAzK,SAAAA,CAAAA,aAAAA,GAAAA,UAAAA,KAAAA;kBAAA0K,mBAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAhCM;;;MAgBA,YAAAtP,UAAAA,CAAAA,EAhBAA;;;;;;;;EAgBLhB,CAAAA,CAAAA,cAAAA,CAAAA,gBAAAA,EAAAA,iBAAAA,CAhBKA;GAAAA,mBAAAA,C;;AI7HL,UAAAA,CAAAA,EAAAA;;;;MAwBO,KAAAuQ,eAAAA,GAAAA,IAxBPA;MA0BD,KAAAC,UAAAA,GAAAA,GA1BCA;MA2BD,KAAAC,WAAAA,GAAAA,GA3BCA;;;;IAwBO,MAAA7K,SAAAA,CAAAA,qCAAAA,CAAAA,GAAAA;kBAAA2K,eAAAA;MAxBP;IA0BD,MAAA3K,SAAAA,CAAAA,MAAAA,CAAAA,GAAAA;kBAAA4K,UAAAA;MA1BC;IA2BD,MAAA5K,SAAAA,CAAAA,OAAAA,CAAAA,GAAAA;kBAAA6K,WAAAA;MA3BC;IA6BD,MAAA7K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAAkC,QAAd,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAAIA,GAAAA,CAAAA,CAAlCA;MA7BC;IA8BD,MAAA9K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAAmC,OAAA5F,CAAAA,CAAAA,cAAAA,CAAdA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAAIA,CAAnCA;MA9BC;IA+BD,MAAA4F,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAAgC,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAAhCA;MA/BC;IAgCD,MAAA9K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAAiC,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAAjCA;MAhCC;IAkCD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAkBA,KAAlBA;MAAmD,QAAjB,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAOA,GAAAA,CAAAA,CAAnDA;MAlCC;IAmCD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAmBA,KAAnBA;MAAqD,OAAA5F,CAAAA,CAAAA,cAAAA,CAAjBA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAOA,CAArDA;MAnCC;IAoCD,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAoBA,KAApBA;MAAgD,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAhDA;MApCC;IAqCD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAqBA,KAArBA;MAAkD,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAlDA;MArCC;IAuCD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAkBA,KAAlBA;MAAmD,QAAjB,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAOA,GAAAA,CAAAA,CAAnDA;MAvCC;IAwCD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAmBA,KAAnBA;MAAqD,OAAA5F,CAAAA,CAAAA,cAAAA,CAAjBA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAOA,CAArDA;MAxCC;IAyCD,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAoBA,KAApBA;MAAgD,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAhDA;MAzCC;IA0CD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAqBA,KAArBA;MAAkD,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAlDA;MA1CC;IA4CD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAKA,KAALA;MAAiD,OAAX,KAAA8K,qCAAAA,CAAAA,EAAWA,CAAAA,IAAAA,CAACA,KAADA,CAAjDA;MA5CC;IA6CD,MAAA9K,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAmD,OAAZ,KAAA8K,qCAAAA,CAAAA,EAAYA,CAAAA,KAAAA,CAACA,KAADA,CAAnDA;MA7CC;IA+CD,MAAA9K,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAmD,QAAhB,KAAA8K,qCAAAA,CAAAA,EAAYA,CAAAA,KAAAA,CAACA,KAADA,CAAIA,GAAAA,CAAAA,CAAnDA;MA/CC;IAgDD,MAAA9K,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA,UAAMA,KAANA;MAAqD,OAAA5F,CAAAA,CAAAA,cAAAA,CAAhBA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAYA,CAAAA,KAAAA,CAACA,KAADA,CAAIA,CAArDA;MAhDC;IAkDD,MAAA4F,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAKA,KAALA;MAAiD,OAAX,KAAA8K,qCAAAA,CAAAA,EAAWA,CAAAA,IAAAA,CAACA,KAADA,CAAjDA;MAlDC;IAmDD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAIA,KAAJA,EAAqBA,KAArBA;MAAgE,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,EAAIA,KAAJA,CAAhEA;MAnDC;IAqDD,MAAA9K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAA+C,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAA/CA;MArDC;IAsDD,MAAA9K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAA+C,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAA/CA;MAtDC;IAuDD,MAAA9K,SAAAA,CAAAA,SAAAA,CAAAA,GAAAA,UAAIA,KAAJA;MAA+C,OAAV,KAAA8K,qCAAAA,CAAAA,EAAUA,CAAAA,GAAAA,CAACA,KAADA,CAA/CA;MAvDC;IAwDD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAKA,KAALA;MAAiD,OAAX,KAAA8K,qCAAAA,CAAAA,EAAWA,CAAAA,IAAAA,CAACA,KAADA,CAAjDA;MAxDC;IAyDD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAKA,KAALA;MAAiD,OAAX,KAAA8K,qCAAAA,CAAAA,EAAWA,CAAAA,IAAAA,CAACA,KAADA,CAAjDA;MAzDC;IA0DD,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,UAAKA,KAALA;MAAiD,OAAX,KAAA8K,qCAAAA,CAAAA,EAAWA,CAAAA,IAAAA,CAACA,KAADA,CAAjDA;MA1DC;IA2DD,MAAA9K,SAAAA,CAAAA,YAAAA,CAAAA,GAAAA,UAAMA,KAANA,EAAuBA,KAAvBA;MAAoE,OAAZ,KAAA8K,qCAAAA,CAAAA,EAAYA,CAAAA,KAAAA,CAACA,KAADA,EAAIA,KAAJA,CAApEA;MA3DC;IA6DD,MAAA9K,SAAAA,CAAAA,WAAAA,CAAAA,GAAAA;MAAsC,OAAb,KAAA8K,qCAAAA,CAAAA,EAAaA,CAAAA,MAAAA,EAAtCA;MA7DC;IAAK,MAAA9K,SAAAA,CAAAA,UAAAA,CAAAA,GAAAA,YAAAA;MAAA5F,CAAAA,CAAAA,CAAAA,CAAAA,kBAAAA,CAAAA,CAAAA,SAAAA,CAAAA,UAAAA,CAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA;MAAAA,CAAAA,CAAAA,OAAAA,CAAAA,gBAAAA,CAAAA,CAAAA,SAAAA,GAAAA,IAAAA;MAwBE,KAAAuQ,eAAAA,GAAoBA,CAAAA,CAAAA,CAAAA,CAAAA,IAxBtBA;MA0BN,KAAAC,UAAAA,GAAkBA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAOA,EA1BnBA;MA2BN,KAAAC,WAAAA,GAAmBA,IAAAA,CAAAA,qCAAAA,CAAAA,EAAOA,GA3BpBA;;MAAL;IA0BD,MAAA7K,SAAAA,CAAAA,CAAAA,GAAAA;kBAAA+K,MAAAA,CAAAA,EAAAA;MA1BC;IA2BD,MAAA/K,SAAAA,CAAAA,EAAAA,GAAAA;kBAAAgL,OAAAA,CAAAA,EAAAA;MA3BC;IAgCD,MAAAhL,SAAAA,CAAAA,GAAAA,GAAAA,UAAAA,KAAAA,EAAAA;kBAAAiL,SAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MADA,YAAAC,SAAAA,CAAAA,CAAAA,KAAAA,CACAA;MAFA,YAAAC,SAAAA,CAAAA,CAAAA,KAAAA,CAEAA;MAHA,YAAAC,SAAAA,CAAAA,CAAAA,KAAAA,CAGAA;MAhCC;IAqCD,MAAApL,SAAAA,CAAAA,GAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA;kBAAAqL,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MADA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CACAA;MAFA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAEAA;MAHA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAGAA;MArCC;IA0CD,MAAAxL,SAAAA,CAAAA,GAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA,EAAAA;kBAAAyL,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MADA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CACAA;MAFA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAEAA;MAHA,YAAAC,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAGAA;MA1CC;IA4CD,MAAA5L,SAAAA,CAAAA,IAAAA,GAAAA,UAAAA,KAAAA;kBAAA6L,UAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA5CC;IA6CD,MAAA7L,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA;kBAAA8L,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MA7CC;IAgDD,MAAA9L,SAAAA,CAAAA,KAAAA,GAAAA,UAAAA,KAAAA,EAAAA;kBAAA+L,WAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MADA,YAAAC,WAAAA,CAAAA,CAAAA,KAAAA,CACAA;MAhDC;IAkDD,MAAAhM,SAAAA,CAAAA,IAAAA,GAAAA,UAAAA,KAAAA;kBAAAiM,UAAAA,CAAAA,CAAAA,KAAAA,CAAAA;MAlDC;IAmDD,MAAAjM,SAAAA,CAAAA,GAAAA,GAAAA,UAAAA,KAAAA,EAAAA,KAAAA;kBAAAkM,UAAAA,CAAAA,CAAAA,KAAAA,EAAAA,KAAAA,CAAAA;MAnDC;IAqDD,MAAAlM,SAAAA,CAAAA,GAAAA \ No newline at end of file diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh new file mode 100755 index 00000000..e59fe4a0 --- /dev/null +++ b/wasm-mappings/ci/script.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -eux + +case "$JOB" in + "test") + cargo test + ;; + "bench") + cargo bench + ;; + "wasm") + rustup target add wasm32-unknown-unknown + cd source-map-mappings-wasm-api/ + + # Non-release builds are broken for wasm32-unknown-unknown targets right now. + # cargo build --target wasm32-unknown-unknown + # test -f target/wasm32-unknown-unknown/debug/source_map_mappings_wasm_api.wasm + + cargo build --release --target wasm32-unknown-unknown + test -f target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm + + rm target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm + cargo build --release --target wasm32-unknown-unknown --features profiling + test -f target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm + ;; + *) + echo "Unknown \$JOB = '$JOB'" + exit 1 +esac diff --git a/wasm-mappings/source-map-mappings-wasm-api/.gitignore b/wasm-mappings/source-map-mappings-wasm-api/.gitignore new file mode 100644 index 00000000..2f7896d1 --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml new file mode 100644 index 00000000..43683b01 --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml @@ -0,0 +1,20 @@ +[package] +authors = ["Nick Fitzgerald ", "Tom Tromey "] +description = "Exported WebAssembly API for the `source-map-mappings` crate." +license = "BSD-3-Clause" +name = "source-map-mappings-wasm-api" +readme = "../README.md" +repository = "https://github.com/mozilla/source-map" +version = "0.5.0" + +[dependencies] +source-map-mappings = { version = "0.5.0", path = ".." } + +[features] +profiling = [] + +[lib] +crate-type = ["cdylib"] + +[profile.release] +debug = true diff --git a/wasm-mappings/source-map-mappings-wasm-api/build.py b/wasm-mappings/source-map-mappings-wasm-api/build.py new file mode 100755 index 00000000..7ff2aab1 --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/build.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +import argparse +import os +import re +import subprocess +import sys + +DESC = """ + +Build, trim, and optimize the `.wasm` file for inclusion in the +`mozilla/source-map` library. + +Requires: + +- wasm-nm: https://github.com/fitzgen/wasm-nm +- wasm-gc: https://github.com/alexcrichton/wasm-gc +- wasm-snip: https://github.com/fitzgen/wasm-snip +- wasm-opt: https://github.com/WebAssembly/binaryen + +""" + +parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=DESC) + +parser.add_argument( + "-g", + "--debug", + action="https://github.com/store_true", + help="Include debug info (the \"name\" section) in the final `.wasm` file.") + +parser.add_argument( + "-p", + "--profiling", + action="https://github.com/store_true", + help="Enable the `profiling` cargo feature.") + +parser.add_argument( + "-o", + "--output", + type=str, + default=None, + help="The path to write the output `.wasm` file to. If not supplied, the `.wasm` file is written to `stdout`.") + +parser.add_argument( + "--no-wasm-opt", + dest="wasm_opt", + action="https://github.com/store_false", + help="Do not run `wasm-opt`.") + +parser.add_argument( + "--no-wasm-gc", + dest="wasm_gc", + action="https://github.com/store_false", + help="Do not run `wasm-gc`.") + +parser.add_argument( + "--no-wasm-snip", + dest="wasm_snip", + action="https://github.com/store_false", + help="Do not run `wasm-snip`.") + +def decode(f): + return f.decode(encoding="utf-8", errors="ignore") + +def run(cmd, **kwargs): + sys.stderr.write(str(cmd) + "\n") + + if "stdout" not in kwargs: + kwargs["stdout"] = subprocess.PIPE + child = subprocess.run(cmd, **kwargs) + if child.returncode != 0: + raise Exception("{} did not exit OK".format(str(cmd))) + return decode(child.stdout) + +def add_path_ext_prefix(path, prefix): + (root, ext) = os.path.splitext(path) + return root + "." + prefix + ext + +def build(args): + cmd = ["cargo", "build", "--release", "--target", "wasm32-unknown-unknown"] + if args.profiling: + cmd.extend(["--features", "profiling"]) + run(cmd) + return "./target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm" + +def wasm_gc(args, wasm_path): + if not args.wasm_gc: + return wasm_path + + out_path = add_path_ext_prefix(wasm_path, "gc") + run(["wasm-gc", wasm_path, out_path]) + return out_path + +SHOULD_SNIP = [ + re.compile(r".*(std|core)(9|::)panicking.*"), + re.compile(r".*(std|core)(3|::)fmt.*"), + re.compile(r".*core(6|::)option(13|::)expect_failed.*"), + re.compile(r".*core(5|::)slice(\d+|::)slice_index_.*_fail.*"), + re.compile(r".*core(3|::)str(\d+|::)slice_.*_fail.*"), + re.compile(r".*core(6|::)result(13|::)unwrap_failed.*"), + re.compile(r".*std(6|::)thread(5|::)local.*"), + re.compile(r".*std(2|::)io(5|::).*"), + re.compile(r"__.*2"), + re.compile(r".*(std|core)(5|::)error.*"), + re.compile(r".*(std|core)(3|::)any(3|::)Any.*"), +] + +def wasm_snip(args, wasm_path): + if not args.wasm_snip: + return wasm_path + + out_path = add_path_ext_prefix(wasm_path, "snip") + + private_functions = run(["wasm-nm", "-j", wasm_path]).splitlines() + + snip_functions = set() + for snip in SHOULD_SNIP: + snip_functions.update(filter(lambda f: re.match(snip, f), + private_functions)) + + run(["wasm-snip", "-o", out_path, wasm_path, *snip_functions]), + return out_path + +def wasm_opt(args, wasm_path): + if not args.wasm_opt: + return wasm_path + + out_path = add_path_ext_prefix(wasm_path, "opt") + + cmd = [ + "wasm-opt", + "-O3", + "-Oz", + "--duplicate-function-elimination", + "-o", out_path, + wasm_path + ] + if args.debug: + cmd.append("-g") + run(cmd) + return out_path + +def main(): + args = parser.parse_args() + os.chdir(os.path.dirname(sys.argv[0])) + + wasm_path = build(args) + wasm_path = wasm_gc(args, wasm_path) + wasm_path = wasm_snip(args, wasm_path) + # GC again after snipping. + wasm_path = wasm_gc(args, wasm_path) + wasm_path = wasm_opt(args, wasm_path) + + if args.output: + run(["cp", wasm_path, args.output]) + else: + run(["cat", wasm_path], stdout=subprocess.STDOUT) + +if __name__ == "__main__": + main() diff --git a/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs b/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs new file mode 100644 index 00000000..d91ed381 --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs @@ -0,0 +1,456 @@ +//! The public JS API to the `source-map-mappings` crate. +//! +//! ## Usage +//! +//! 1. Instantiate the WebAssembly module, supplying a JS implementation of +//! `mapping_callback`. +//! +//! 2. Allocate space for the mappings string with `allocate_mappings`. +//! +//! 3. Initialize the mappings string by copying the JS `String`'s data into it. +//! +//! 4. Parse the mappings with `parse_mappings`. Handle errors, if any. +//! +//! 5. Query the resulting `Mappings` structure as needed with +//! `by_generated_location`, `by_original_location`, `compute_column_spans`, +//! `original_location_for`, `generated_location_for`, and +//! `all_generated_locations_for` as needed. +//! +//! 6. When finished with `Mappings` structure, dispose of it with +//! `free_mappings`. + +// NB: every exported function must be `#[no_mangle]` and `pub extern "C"`. + +#![deny(missing_docs)] + +extern crate source_map_mappings; + +use source_map_mappings::{Bias, Error, Mapping, Mappings}; +use std::mem; +use std::ptr; +use std::process; +use std::slice; + +#[cfg(feature = "profiling")] +mod observer { + use source_map_mappings; + + macro_rules! define_raii_observer { + ( $name:ident , $ctor:ident , $dtor:ident ) => { + #[derive(Debug)] + pub struct $name; + + impl Default for $name { + #[inline] + fn default() -> $name { + extern "C" { + fn $ctor(); + } + unsafe { + $ctor(); + } + $name + } + } + + impl Drop for $name { + #[inline] + fn drop(&mut self) { + extern "C" { + fn $dtor(); + } + unsafe { + $dtor(); + } + } + } + } + } + + define_raii_observer!(ParseMappings, start_parse_mappings, end_parse_mappings); + define_raii_observer!( + SortByOriginalLocation, + start_sort_by_original_location, + end_sort_by_original_location + ); + define_raii_observer!( + SortByGeneratedLocation, + start_sort_by_generated_location, + end_sort_by_generated_location + ); + define_raii_observer!( + ComputeColumnSpans, + start_compute_column_spans, + end_compute_column_spans + ); + define_raii_observer!( + OriginalLocationFor, + start_original_location_for, + end_original_location_for + ); + define_raii_observer!( + GeneratedLocationFor, + start_generated_location_for, + end_generated_location_for + ); + define_raii_observer!( + AllGeneratedLocationsFor, + start_all_generated_locations_for, + end_all_generated_locations_for + ); + + #[derive(Debug, Default)] + pub struct Observer; + + impl source_map_mappings::Observer for Observer { + type ParseMappings = ParseMappings; + type SortByOriginalLocation = SortByOriginalLocation; + type SortByGeneratedLocation = SortByGeneratedLocation; + type ComputeColumnSpans = ComputeColumnSpans; + type OriginalLocationFor = OriginalLocationFor; + type GeneratedLocationFor = GeneratedLocationFor; + type AllGeneratedLocationsFor = AllGeneratedLocationsFor; + } +} + +#[cfg(not(feature = "profiling"))] +mod observer { + pub type Observer = (); +} + +use observer::Observer; + +static mut LAST_ERROR: Option = None; + +/// Get the last error's error code, or 0 if there was none. +/// +/// See `source_map_mappings::Error` for the error code definitions. +#[no_mangle] +pub extern "C" fn get_last_error() -> u32 { + unsafe { + match LAST_ERROR { + None => 0, + Some(e) => e as u32, + } + } +} + +#[inline] +fn assert_pointer_is_word_aligned(p: *mut u8) { + debug_assert_eq!(p as usize & (mem::size_of::() - 1), 0); +} + +/// Allocate space for a mappings string of the given size (in bytes). +/// +/// It is the JS callers responsibility to initialize the resulting buffer by +/// copying the JS `String` holding the source map's "mappings" into it (encoded +/// in ascii). +#[no_mangle] +pub extern "C" fn allocate_mappings(size: usize) -> *mut u8 { + // Make sure that we don't lose any bytes from size in the remainder. + let size_in_units_of_usize = (size + mem::size_of::() - 1) / mem::size_of::(); + + // Make room for two additional `usize`s: we'll stuff capacity and length in + // there. + let mut vec: Vec = Vec::with_capacity(size_in_units_of_usize + 2); + + // And do the stuffing. + let capacity = vec.capacity(); + vec.push(capacity); + vec.push(size); + + // Leak the vec's elements and get a pointer to them. + let ptr = vec.as_mut_ptr(); + debug_assert!(!ptr.is_null()); + mem::forget(vec); + + // Advance the pointer past our stuffed data and return it to JS, so that JS + // can write the mappings string into it. + let ptr = ptr.wrapping_offset(2) as *mut u8; + assert_pointer_is_word_aligned(ptr); + ptr +} + +#[inline] +fn constrain<'a, T>(_scope: &'a (), reference: &'a T) -> &'a T +where + T: ?Sized, +{ + reference +} + +/// Parse the given initialized mappings string into a `Mappings` structure. +/// +/// Returns `NULL` on failure, or a pointer to the parsed `Mappings` structure +/// on success. +/// +/// In the case of failure, the error can be retrieved with `get_last_error`. +/// +/// In the case of success, the caller takes ownership of the result, and must +/// call `free_mappings` to destroy it when finished. +/// +/// In both the success or failure cases, the caller gives up ownership of the +/// input mappings string and must not use it again. +#[no_mangle] +pub extern "C" fn parse_mappings(mappings: *mut u8) -> *mut Mappings { + assert_pointer_is_word_aligned(mappings); + let mappings = mappings as *mut usize; + + // Unstuff the data we put just before the pointer to the mappings + // string. + let capacity_ptr = mappings.wrapping_offset(-2); + debug_assert!(!capacity_ptr.is_null()); + let capacity = unsafe { *capacity_ptr }; + + let size_ptr = mappings.wrapping_offset(-1); + debug_assert!(!size_ptr.is_null()); + let size = unsafe { *size_ptr }; + + // Construct the input slice from the pointer and parse the mappings. + let result = unsafe { + let input = slice::from_raw_parts(mappings as *const u8, size); + let this_scope = (); + let input = constrain(&this_scope, input); + source_map_mappings::parse_mappings(input) + }; + + // Deallocate the mappings string and its two prefix words. + let size_in_usizes = (size + mem::size_of::() - 1) / mem::size_of::(); + unsafe { + Vec::::from_raw_parts(capacity_ptr, size_in_usizes + 2, capacity); + } + + // Return the result, saving any errors on the side for later inspection by + // JS if required. + match result { + Ok(mappings) => Box::into_raw(Box::new(mappings)), + Err(e) => { + unsafe { + LAST_ERROR = Some(e); + } + ptr::null_mut() + } + } +} + +/// Destroy the given `Mappings` structure. +/// +/// The caller gives up ownership of the mappings and must not use them again. +#[no_mangle] +pub extern "C" fn free_mappings(mappings: *mut Mappings) { + unsafe { + Box::from_raw(mappings); + } +} + +#[inline] +unsafe fn mappings_mut<'a>( + _scope: &'a (), + mappings: *mut Mappings, +) -> &'a mut Mappings { + mappings.as_mut().unwrap() +} + +extern "C" { + fn mapping_callback( + // These two parameters are always valid. + generated_line: u32, + generated_column: u32, + + // The `last_generated_column` parameter is only valid if + // `has_last_generated_column` is `true`. + has_last_generated_column: bool, + last_generated_column: u32, + + // The `source`, `original_line`, and `original_column` parameters are + // only valid if `has_original` is `true`. + has_original: bool, + source: u32, + original_line: u32, + original_column: u32, + + // The `name` parameter is only valid if `has_name` is `true`. + has_name: bool, + name: u32, + ); +} + +#[inline] +unsafe fn invoke_mapping_callback(mapping: &Mapping) { + let generated_line = mapping.generated_line; + let generated_column = mapping.generated_column; + + let (has_last_generated_column, last_generated_column) = + if let Some(last_generated_column) = mapping.last_generated_column { + (true, last_generated_column) + } else { + (false, 0) + }; + + let (has_original, source, original_line, original_column, has_name, name) = + if let Some(original) = mapping.original.as_ref() { + let (has_name, name) = if let Some(name) = original.name { + (true, name) + } else { + (false, 0) + }; + + ( + true, + original.source, + original.original_line, + original.original_column, + has_name, + name, + ) + } else { + (false, 0, 0, 0, false, 0) + }; + + mapping_callback( + generated_line, + generated_column, + has_last_generated_column, + last_generated_column, + has_original, + source, + original_line, + original_column, + has_name, + name, + ); +} + +/// Invoke the `mapping_callback` on each mapping in the given `Mappings` +/// structure, in order of generated location. +#[no_mangle] +pub extern "C" fn by_generated_location(mappings: *mut Mappings) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + + mappings + .by_generated_location() + .iter() + .for_each(|m| unsafe { + invoke_mapping_callback(m); + }); +} + +/// Compute column spans for the given mappings. +#[no_mangle] +pub extern "C" fn compute_column_spans(mappings: *mut Mappings) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + + mappings.compute_column_spans(); +} + +/// Invoke the `mapping_callback` on each mapping in the given `Mappings` +/// structure that has original location information, in order of original +/// location. +#[no_mangle] +pub extern "C" fn by_original_location(mappings: *mut Mappings) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + + mappings.by_original_location().for_each(|m| unsafe { + invoke_mapping_callback(m); + }); +} + +#[inline] +fn u32_to_bias(bias: u32) -> Bias { + match bias { + 1 => Bias::GreatestLowerBound, + 2 => Bias::LeastUpperBound, + otherwise => if cfg!(debug_assertions) { + panic!( + "Invalid `Bias = {}`; must be `Bias::GreatestLowerBound = {}` or \ + `Bias::LeastUpperBound = {}`", + otherwise, + Bias::GreatestLowerBound as u32, + Bias::LeastUpperBound as u32, + ) + } else { + process::abort() + }, + } +} + +/// Find the mapping for the given generated location, if any exists. +/// +/// If a mapping is found, the `mapping_callback` is invoked with it +/// once. Otherwise, the `mapping_callback` is not invoked at all. +#[no_mangle] +pub extern "C" fn original_location_for( + mappings: *mut Mappings, + generated_line: u32, + generated_column: u32, + bias: u32, +) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + let bias = u32_to_bias(bias); + + if let Some(m) = mappings.original_location_for(generated_line, generated_column, bias) { + unsafe { + invoke_mapping_callback(m); + } + } +} + +/// Find the mapping for the given original location, if any exists. +/// +/// If a mapping is found, the `mapping_callback` is invoked with it +/// once. Otherwise, the `mapping_callback` is not invoked at all. +#[no_mangle] +pub extern "C" fn generated_location_for( + mappings: *mut Mappings, + source: u32, + original_line: u32, + original_column: u32, + bias: u32, +) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + let bias = u32_to_bias(bias); + + if let Some(m) = mappings.generated_location_for(source, original_line, original_column, bias) { + unsafe { + invoke_mapping_callback(m); + } + } +} + +/// Find all mappings for the given original location, and invoke the +/// `mapping_callback` on each of them. +/// +/// If `has_original_column` is `true`, then the `mapping_callback` is only +/// invoked with mappings with matching source and original line **and** +/// original column is equal to `original_column`. If `has_original_column` is +/// `false`, then the `original_column` argument is ignored, and the +/// `mapping_callback` is invoked on all mappings with matching source and +/// original line. +#[no_mangle] +pub extern "C" fn all_generated_locations_for( + mappings: *mut Mappings, + source: u32, + original_line: u32, + has_original_column: bool, + original_column: u32, +) { + let this_scope = (); + let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + + let original_column = if has_original_column { + Some(original_column) + } else { + None + }; + + for m in mappings.all_generated_locations_for(source, original_line, original_column) { + unsafe { + invoke_mapping_callback(m); + } + } +} diff --git a/wasm-mappings/source-map-mappings-wasm-api/who-calls.py b/wasm-mappings/source-map-mappings-wasm-api/who-calls.py new file mode 100755 index 00000000..aa908427 --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/who-calls.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 + +import argparse +import re +import subprocess + +DESC = """ + +List the callers of some function in the given `.wasm` file. + +Constructs the call graph of functions in the `.wasm` file and then queries +edges in that call graph. + +Requires that the `wasm-objdump` tool from the WABT[0] is installed and on the +`$PATH`. + +[0]: https://github.com/WebAssembly/wabt + +## Example Usage + +Print every caller of `std::panicking::begin_panic`: + + $ ./who-calls.py path/to/something.wasm \\ + --function "std::panicking::begin_panic::h59c9bbae5c8cc295" + +Print the top 5 largest functions and their callers: + + $ ./who-calls.py path/to/something.wasm --top + +""" + +parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=DESC) + +parser.add_argument( + "wasm_file", + type=str, + help="The input `.wasm` file.") + +parser.add_argument( + "--function", + type=str, + help="The function whose callers should be listed.") + +parser.add_argument( + "-t", + "--top", + type=int, + default=None, + help="Display the largest N functions and their callers") + +parser.add_argument( + "-d", + "--max-depth", + type=int, + default=None, + help="The maximum call stack depth to display") + +def decode(f): + return f.decode(encoding="utf-8", errors="ignore") + +def run(cmd, **kwargs): + kwargs["stdout"] = subprocess.PIPE + child = subprocess.run(cmd, **kwargs) + if child.returncode != 0: + raise Exception("{} did not exit OK".format(str(cmd))) + return decode(child.stdout) + +def disassemble(args): + return run(["wasm-objdump", "-d", args.wasm_file]) + +START_FUNCTION = re.compile(r"^(\w+) <([\w<>:\s]+)>:$") +CALL_FUNCTION = re.compile(r"^ \w+: [\w ]*\|\s*call \w+ <([\w<>:\s]+)>$") + +def parse_call_graph(disassembly, args): + call_graph = {} + current_function = None + + for line in disassembly.splitlines(): + match = re.match(START_FUNCTION, line) + if match: + current_function = match.groups()[1] + call_graph[current_function] = set() + continue + + match = re.match(CALL_FUNCTION, line) + if match and current_function: + call_graph[current_function].add(match.groups()[0]) + + return call_graph + +def parse_top_functions(disassembly, args): + functions = [] + last_function = None + + for line in disassembly.splitlines(): + match = re.match(START_FUNCTION, line) + if match: + (start, function) = match.groups() + start = int(start, 16) + if last_function: + (f, last_start) = last_function + functions.append((f, start - last_start)) + last_function = (function, start) + + top_functions = sorted(functions, key=lambda a: a[1], reverse=True) + return top_functions[:args.top] + +def reverse_call_graph(call_graph, args): + reversed_call_graph = {} + + for function, calls in call_graph.items(): + if function not in reversed_call_graph: + reversed_call_graph[function] = set() + + for call in calls: + if call not in reversed_call_graph: + reversed_call_graph[call] = set() + reversed_call_graph[call].add(function) + + return reversed_call_graph + +def print_callers(reversed_call_graph, args, function=None, depth=0, seen=set()): + if not function: + function = args.function + seen.add(function) + + if depth == 0: + depth += 1 + print("{}".format(function)) + if function not in reversed_call_graph: + print(" ") + return + + if args.max_depth is None or depth < args.max_depth: + for caller in reversed_call_graph[function]: + if caller in seen: + continue + + indent = "" + for _ in range(0, depth): + indent += " " + + print("{}⬑ {}".format(indent, caller)) + + print_callers(reversed_call_graph, args, function=caller, depth=depth+1, seen=seen) + + seen.remove(function) + +def main(): + args = parser.parse_args() + disassembly = disassemble(args) + call_graph = parse_call_graph(disassembly, args) + reversed_call_graph = reverse_call_graph(call_graph, args) + + if args.function: + print_callers(reversed_call_graph, args) + elif args.top: + top_functions = parse_top_functions(disassembly, args) + for f, size in top_functions: + print(size, "bytes: ", end="") + print_callers(reversed_call_graph, args, function=f) + else: + raise Exception("Must use one of --function or --top") + +if __name__ == "__main__": + main() diff --git a/wasm-mappings/src/comparators.rs b/wasm-mappings/src/comparators.rs new file mode 100644 index 00000000..23f78878 --- /dev/null +++ b/wasm-mappings/src/comparators.rs @@ -0,0 +1,121 @@ +//! Comparator functions for sorting mappings in different ways. + +use super::{Mapping, OriginalLocation}; +use std::cmp::Ordering; +use std::fmt; + +/// A function that can compare two `T`s. +pub trait ComparatorFunction: fmt::Debug { + /// Compare the given values. + fn compare(&T, &T) -> Ordering; +} + +impl ComparatorFunction> for F +where + F: ComparatorFunction, +{ + #[inline] + fn compare(a: &Option, b: &Option) -> Ordering { + match (a, b) { + (&None, &None) => Ordering::Equal, + (&Some(_), &None) => Ordering::Less, + (&None, &Some(_)) => Ordering::Greater, + (&Some(ref a), &Some(ref b)) => F::compare(a, b), + } + } +} + +// Yes, using this style of comparison instead of `cmp.then(cmp2).then(cmp3)` is +// actually a big performance win in practice: +// +// ``` +// $ cargo benchcmp control variable +// name control ns/iter variable ns/iter diff ns/iter diff % speedup +// bench_parse_part_of_scala_js_source_map 2,029,981 1,290,716 -739,265 -36.42% x 1.57 +// ``` +// +// This doesn't seem right, but you can't argue with those numbers... +macro_rules! compare { + ($a:expr, $b:expr) => { + let cmp = ($a as i64) - ($b as i64); + if cmp < 0 { + return Ordering::Less; + } else if cmp > 0 { + return Ordering::Greater; + } + } +} + +/// Sort mappings by their generated location, but don't compare generated +/// lines. This is useful for when we know that all mappings being sorted have +/// the same generated line number. +#[derive(Debug)] +pub struct ByGeneratedTail; + +impl ComparatorFunction for ByGeneratedTail { + #[inline] + fn compare(a: &Mapping, b: &Mapping) -> Ordering { + compare!(a.generated_column, b.generated_column); + ByOriginalLocation::compare(&a.original, &b.original) + } +} + +/// Sort mappings by their original locations, breaking ties by their generated +/// locations. +#[derive(Debug)] +pub struct ByOriginalLocation; + +impl ComparatorFunction for ByOriginalLocation { + #[inline] + fn compare(a: &Mapping, b: &Mapping) -> Ordering { + let c = ByOriginalLocation::compare(&a.original, &b.original); + match c { + Ordering::Less | Ordering::Greater => c, + Ordering::Equal => { + compare!(a.generated_line, b.generated_line); + compare!(a.generated_column, b.generated_column); + Ordering::Equal + } + } + } +} + +impl ComparatorFunction for ByOriginalLocation { + #[inline] + fn compare(a: &OriginalLocation, b: &OriginalLocation) -> Ordering { + compare!(a.source, b.source); + compare!(a.original_line, b.original_line); + compare!(a.original_column, b.original_column); + a.name.cmp(&b.name) + } +} + +/// Assuming mappings are in the same original source, sort mappings by their +/// original locations, breaking ties by their generated locations. +#[derive(Debug)] +pub struct ByOriginalLocationSameSource; + +impl ComparatorFunction for ByOriginalLocationSameSource { + #[inline] + fn compare(a: &Mapping, b: &Mapping) -> Ordering { + let c = ByOriginalLocationSameSource::compare(&a.original, &b.original); + match c { + Ordering::Less | Ordering::Greater => c, + Ordering::Equal => { + compare!(a.generated_line, b.generated_line); + compare!(a.generated_column, b.generated_column); + Ordering::Equal + } + } + } +} + +impl ComparatorFunction for ByOriginalLocationSameSource { + #[inline] + fn compare(a: &OriginalLocation, b: &OriginalLocation) -> Ordering { + debug_assert_eq!(a.source, b.source); + compare!(a.original_line, b.original_line); + compare!(a.original_column, b.original_column); + a.name.cmp(&b.name) + } +} diff --git a/wasm-mappings/src/lib.rs b/wasm-mappings/src/lib.rs new file mode 100755 index 00000000..e93736f6 --- /dev/null +++ b/wasm-mappings/src/lib.rs @@ -0,0 +1,688 @@ +#![deny(missing_debug_implementations)] + +extern crate rand; +extern crate vlq; + +pub mod comparators; + +use comparators::ComparatorFunction; +use std::cmp; +use std::marker::PhantomData; +use std::mem; +use std::slice; +use std::u32; + +/// Errors that can occur during parsing. +#[derive(Copy, Clone, Debug)] +#[repr(u32)] +pub enum Error { + // NB: 0 is reserved for OK. + /// The mappings contained a negative line, column, source index, or name + /// index. + UnexpectedNegativeNumber = 1, + + /// The mappings contained a number larger than `u32::MAX`. + UnexpectedlyBigNumber = 2, + + /// Reached EOF while in the middle of parsing a VLQ. + VlqUnexpectedEof = 3, + + /// Encountered an invalid base 64 character while parsing a VLQ. + VlqInvalidBase64 = 4, + + /// VLQ encountered a number that, when decoded, would not fit in + /// an i64. + VlqOverflow = 5, +} + +impl From for Error { + #[inline] + fn from(e: vlq::Error) -> Error { + match e { + vlq::Error::UnexpectedEof => Error::VlqUnexpectedEof, + vlq::Error::InvalidBase64(_) => Error::VlqInvalidBase64, + vlq::Error::Overflow => Error::VlqOverflow, + } + } +} + +/// When doing fuzzy searching, whether to slide the next larger or next smaller +/// mapping from the queried location. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u32)] +pub enum Bias { + // XXX: make sure these values always match `mozilla/source-map`'s + // `SourceMapConsumer.{GreatestLower,LeastUpper}Bound` values! + /// Slide to the next smaller mapping. + GreatestLowerBound = 1, + + /// Slide to the next larger mapping. + LeastUpperBound = 2, +} + +impl Default for Bias { + #[inline] + fn default() -> Bias { + Bias::GreatestLowerBound + } +} + +/// A trait for defining a set of RAII types that can observe the start and end +/// of various operations and queries we perform in their constructors and +/// destructors. +/// +/// This is also implemented for `()` as the "null observer" that doesn't +/// actually do anything. +pub trait Observer: Default { + /// Observe the parsing of the `"mappings"` string. + type ParseMappings: Default; + + /// Observe sorting parsed mappings by original location. + type SortByOriginalLocation: Default; + + /// Observe sorting parsed mappings by generated location. + type SortByGeneratedLocation: Default; + + /// Observe computing column spans. + type ComputeColumnSpans: Default; + + /// Observe querying what the original location for some generated location + /// is. + type OriginalLocationFor: Default; + + /// Observe querying what the generated location for some original location + /// is. + type GeneratedLocationFor: Default; + + /// Observe querying what all generated locations for some original location + /// is. + type AllGeneratedLocationsFor: Default; +} + +impl Observer for () { + type ParseMappings = (); + type SortByOriginalLocation = (); + type SortByGeneratedLocation = (); + type ComputeColumnSpans = (); + type OriginalLocationFor = (); + type GeneratedLocationFor = (); + type AllGeneratedLocationsFor = (); +} + +#[derive(Debug)] +enum LazilySorted { + Sorted(Vec, PhantomData, PhantomData), + Unsorted(Vec), +} + +impl LazilySorted +where + F: comparators::ComparatorFunction, + O: Default, +{ + #[inline] + fn sort(&mut self) -> &[T] { + let me = mem::replace(self, LazilySorted::Unsorted(vec![])); + let items = match me { + LazilySorted::Sorted(items, ..) => items, + LazilySorted::Unsorted(mut items) => { + let _observer = O::default(); + items.sort_unstable_by(F::compare); + items + } + }; + mem::replace(self, LazilySorted::Sorted(items, PhantomData, PhantomData)); + unwrap(self.sorted()) + } + + #[inline] + fn unsorted(&mut self) -> Option<&mut Vec> { + match *self { + LazilySorted::Unsorted(ref mut items) => Some(items), + LazilySorted::Sorted(..) => None, + } + } + + #[inline] + fn sorted(&self) -> Option<&[T]> { + match *self { + LazilySorted::Sorted(ref items, ..) => Some(items), + LazilySorted::Unsorted(_) => None, + } + } + + #[inline] + fn is_empty(&self) -> bool { + match *self { + LazilySorted::Sorted(ref items, ..) | + LazilySorted::Unsorted(ref items) => items.is_empty() + } + } +} + +/// A parsed set of mappings that can be queried. +/// +/// Constructed via `parse_mappings`. +#[derive(Debug)] +pub struct Mappings +where + O: Observer +{ + by_generated: Vec, + computed_column_spans: bool, + observer: O, + + // The `by_original` field maps source index to mappings within that + // original source. This lets us essentially do bucket sort on a per-source + // basis, and also enables lazily sorting different source's mappings. + by_original: Option>>, +} + +#[cfg(debug_assertions)] +fn unwrap(o: Option) -> T { + o.unwrap() +} + +#[cfg(not(debug_assertions))] +#[inline] +fn unwrap(o: Option) -> T { + use std::process; + match o { + Some(t) => t, + None => process::abort(), + } +} + +impl Mappings { + /// Get the full set of mappings, ordered by generated location. + #[inline] + pub fn by_generated_location(&self) -> &[Mapping] { + &self.by_generated + } + + /// Compute the last generated column of each mapping. + /// + /// After this method has been called, any mappings with + /// `last_generated_column == None` means that the mapping spans to the end + /// of the line. + #[inline] + pub fn compute_column_spans(&mut self) { + if self.computed_column_spans { + return; + } + self.compute_column_spans_slow_path(); + } + + #[inline(never)] + fn compute_column_spans_slow_path(&mut self) { + debug_assert!(!self.computed_column_spans); + + let _observer = O::ComputeColumnSpans::default(); + + let mut by_generated = self.by_generated.iter_mut().peekable(); + while let Some(this_mapping) = by_generated.next() { + if let Some(next_mapping) = by_generated.peek() { + if this_mapping.generated_line == next_mapping.generated_line { + this_mapping.last_generated_column = Some(next_mapping.generated_column); + } + } + } + + self.computed_column_spans = true; + } + + #[inline] + fn source_buckets(&mut self) -> &mut [LazilySorted] { + if let Some(ref mut buckets) = self.by_original { + return buckets; + } + self.source_buckets_slow_path() + } + + #[inline(never)] + fn source_buckets_slow_path(&mut self) -> &mut [LazilySorted] { + debug_assert!(self.by_original.is_none()); + + self.compute_column_spans(); + + let _observer = O::SortByOriginalLocation::default(); + + let mut originals = vec![]; + for m in self.by_generated.iter().filter(|m| m.original.is_some()) { + let source = unwrap(m.original.as_ref()).source as usize; + while originals.len() <= source { + originals.push(LazilySorted::Unsorted(vec![])); + } + unwrap(originals[source].unsorted()).push(m.clone()); + } + + self.by_original = Some(originals); + unwrap(self.by_original.as_mut().map(|x| &mut x[..])) + } + + /// Get the set of mappings that have original location information for the + /// given source and ordered by original location. + #[inline] + pub fn by_original_source(&mut self, source: u32) -> &[Mapping] { + if let Some(ms) = self.source_buckets().get_mut(source as usize) { + ms.sort() + } else { + &[] + } + } + + /// Iterate over all mappings that contain original location information, + /// sorted by their original location information. + #[inline] + pub fn by_original_location(&mut self) -> ByOriginalLocation { + ByOriginalLocation { + buckets: self.source_buckets().iter_mut(), + this_bucket: [].iter(), + } + } + + /// Get the mapping closest to the given generated location, if any exists. + pub fn original_location_for( + &self, + generated_line: u32, + generated_column: u32, + bias: Bias, + ) -> Option<&Mapping> { + let _observer = O::OriginalLocationFor::default(); + + let by_generated = self.by_generated_location(); + + let position = by_generated.binary_search_by(|m| { + m.generated_line + .cmp(&generated_line) + .then(m.generated_column.cmp(&generated_column)) + }); + + match position { + Ok(idx) => Some(&by_generated[idx]), + Err(idx) => match bias { + Bias::LeastUpperBound => by_generated.get(idx), + Bias::GreatestLowerBound => if idx == 0 { + None + } else { + by_generated.get(idx - 1) + }, + }, + } + } + + /// Get the mapping closest to the given original location, if any exists. + pub fn generated_location_for( + &mut self, + source: u32, + original_line: u32, + original_column: u32, + bias: Bias, + ) -> Option<&Mapping> { + let _observer = O::GeneratedLocationFor::default(); + + let position = { + let by_original = self.by_original_source(source); + + by_original.binary_search_by(|m| { + let original = unwrap(m.original.as_ref()); + original + .source + .cmp(&source) + .then(original.original_line.cmp(&original_line)) + .then(original.original_column.cmp(&original_column)) + }) + }; + + let idx = match position { + Ok(idx) => return Some(&self.by_original_source(source)[idx]), + Err(idx) => idx, + }; + + match bias { + Bias::LeastUpperBound => if idx == self.by_original_source(source).len() { + // Slide down to the next source's set of mappings. + let mut source = source + 1; + while unwrap(self.by_original.as_ref()) + .get(source as usize) + .map_or(false, |b| b.is_empty()) + { + source += 1; + } + unwrap(self.by_original.as_mut()) + .get_mut(source as usize) + .and_then(|ms| ms.sort().first()) + } else { + self.by_original_source(source).get(idx) + }, + + Bias::GreatestLowerBound => if idx == 0 { + if source == 0 { + return None; + } + + // Slide up to the previous source's set of mappings. + let mut source = source - 1; + while source > 0 && unwrap(self.by_original.as_ref()) + .get(source as usize) + .map_or(false, |b| b.is_empty()) + { + source -= 1; + } + unwrap(self.by_original.as_mut()) + .get_mut(source as usize) + .and_then(|ms| ms.sort().first()) + } else { + self.by_original_source(source).get(idx - 1) + }, + } + } + + /// Get all mappings at the given original location. + /// + /// If `original_column` is `None`, get all mappings on the given source and + /// original line regardless what columns they have. If `original_column` is + /// `Some`, only return mappings for which all of source, original line, and + /// original column match. + pub fn all_generated_locations_for( + &mut self, + source: u32, + original_line: u32, + original_column: Option, + ) -> AllGeneratedLocationsFor { + let _observer = O::AllGeneratedLocationsFor::default(); + + let query_column = original_column.unwrap_or(0); + + let by_original = self.by_original_source(source); + + let compare = |m: &Mapping| { + let original: &OriginalLocation = unwrap(m.original.as_ref()); + debug_assert_eq!(unwrap(m.original.as_ref()).source, source); + original.original_line.cmp(&original_line) + .then(original.original_column.cmp(&query_column)) + }; + + let idx = by_original.binary_search_by(&compare); + let mut idx = match idx { + Ok(idx) | Err(idx) => idx, + }; + + // If there are multiple mappings for this original location, the binary + // search gives no guarantees that this is the index for the first of + // them, so back up to the first. + while idx > 0 && compare(&by_original[idx - 1]) == cmp::Ordering::Equal { + idx -= 1; + } + + let (mappings, original_line, original_column) = if idx < by_original.len() { + let orig = unwrap(by_original[idx].original.as_ref()); + let mappings = by_original[idx..].iter(); + + // Fuzzy line matching only happens when we don't have a column. + let original_line = if original_column.is_some() { + original_line + } else { + orig.original_line + }; + + let original_column = if original_column.is_some() { + Some(orig.original_column) + } else { + None + }; + + (mappings, original_line, original_column) + } else { + ([].iter(), original_line, original_column) + }; + + AllGeneratedLocationsFor { + mappings, + original_line, + original_column, + } + } +} + +impl Default for Mappings { + #[inline] + fn default() -> Mappings { + Mappings { + by_generated: vec![], + by_original: None, + computed_column_spans: false, + observer: Default::default(), + } + } +} + +/// An iterator returned by `Mappings::by_original_location`. +#[derive(Debug)] +pub struct ByOriginalLocation<'a, O: 'a> { + buckets: slice::IterMut<'a, LazilySorted>, + this_bucket: slice::Iter<'a, Mapping>, +} + +impl<'a, O: 'a + Default> Iterator for ByOriginalLocation<'a, O> { + type Item = &'a Mapping; + + #[inline] + fn next(&mut self) -> Option { + loop { + if let Some(m) = self.this_bucket.next() { + return Some(m); + } + + if let Some(b) = self.buckets.next() { + self.this_bucket = b.sort().iter(); + continue; + } + + return None; + } + } +} + +/// An iterator returned by `Mappings::all_generated_locations_for`. +#[derive(Debug)] +pub struct AllGeneratedLocationsFor<'a> { + mappings: slice::Iter<'a, Mapping>, + original_line: u32, + original_column: Option, +} + +impl<'a> Iterator for AllGeneratedLocationsFor<'a> { + type Item = &'a Mapping; + + #[inline] + fn next(&mut self) -> Option { + match self.mappings.next() { + None => None, + Some(m) => { + let m_orig = unwrap(m.original.as_ref()); + + if m_orig.original_line != self.original_line { + return None; + } + + if let Some(original_column) = self.original_column { + if m_orig.original_column != original_column { + return None; + } + } + + Some(m) + } + } + } +} + +/// A single bidirectional mapping. +/// +/// Always contains generated location information. +/// +/// Might contain original location information, and if so, might also have an +/// associated name. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Mapping { + /// The generated line. + pub generated_line: u32, + + /// The generated column. + pub generated_column: u32, + + /// The end column of this mapping's generated location span. + /// + /// Before `Mappings::computed_column_spans` has been called, this is always + /// `None`. After `Mappings::computed_column_spans` has been called, it + /// either contains `Some` column at which the generated location ends + /// (exclusive), or it contains `None` if it spans until the end of the + /// generated line. + pub last_generated_column: Option, + + /// The original location information, if any. + pub original: Option, +} + +impl Default for Mapping { + #[inline] + fn default() -> Mapping { + Mapping { + generated_line: 0, + generated_column: 0, + last_generated_column: None, + original: None, + } + } +} + +/// Original location information within a mapping. +/// +/// Contains a source filename, an original line, and an original column. Might +/// also contain an associated name. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct OriginalLocation { + /// The source filename. + pub source: u32, + + /// The original line. + pub original_line: u32, + + /// The original column. + pub original_column: u32, + + /// The associated name, if any. + pub name: Option, +} + +#[inline] +fn is_mapping_separator(byte: u8) -> bool { + byte == b';' || byte == b',' +} + +#[inline] +fn read_relative_vlq(previous: &mut u32, input: &mut B) -> Result<(), Error> +where + B: Iterator, +{ + let decoded = vlq::decode(input)?; + let (new, overflowed) = (*previous as i64).overflowing_add(decoded); + if overflowed || new > (u32::MAX as i64) { + return Err(Error::UnexpectedlyBigNumber); + } + + if new < 0 { + return Err(Error::UnexpectedNegativeNumber); + } + + *previous = new as u32; + Ok(()) +} + +/// Parse a source map's `"mappings"` string into a queryable `Mappings` +/// structure. +pub fn parse_mappings(input: &[u8]) -> Result, Error> { + let _observer = O::ParseMappings::default(); + + let mut generated_line = 0; + let mut generated_column = 0; + let mut original_line = 0; + let mut original_column = 0; + let mut source = 0; + let mut name = 0; + let mut generated_line_start_index = 0; + + let mut mappings = Mappings::default(); + + // `input.len() / 2` is the upper bound on how many mappings the string + // might contain. There would be some sequence like `A,A,A,...` or + // `A;A;A;...`. + let mut by_generated = Vec::with_capacity(input.len() / 2); + + let mut input = input.iter().cloned().peekable(); + + while let Some(byte) = input.peek().cloned() { + match byte { + b';' => { + generated_line += 1; + generated_column = 0; + unwrap(input.next()); + + // Because mappings are sorted with regards to generated line + // due to the encoding format, and sorting by generated location + // starts by comparing generated line, we can sort only the + // smaller subsequence of this generated line's mappings and end + // up with a fully sorted array. + if generated_line_start_index < by_generated.len() { + let _observer = O::SortByGeneratedLocation::default(); + by_generated[generated_line_start_index..].sort_unstable_by(comparators::ByGeneratedTail::compare); + generated_line_start_index = by_generated.len(); + } + } + b',' => { + unwrap(input.next()); + } + _ => { + let mut mapping = Mapping::default(); + mapping.generated_line = generated_line; + + // First is a generated column that is always present. + read_relative_vlq(&mut generated_column, &mut input)?; + mapping.generated_column = generated_column as u32; + + // Read source, original line, and original column if the + // mapping has them. + mapping.original = if input.peek().cloned().map_or(true, is_mapping_separator) { + None + } else { + read_relative_vlq(&mut source, &mut input)?; + read_relative_vlq(&mut original_line, &mut input)?; + read_relative_vlq(&mut original_column, &mut input)?; + + Some(OriginalLocation { + source: source, + original_line: original_line, + original_column: original_column, + name: if input.peek().cloned().map_or(true, is_mapping_separator) { + None + } else { + read_relative_vlq(&mut name, &mut input)?; + Some(name) + }, + }) + }; + + by_generated.push(mapping); + } + } + } + + if generated_line_start_index < by_generated.len() { + let _observer = O::SortByGeneratedLocation::default(); + by_generated[generated_line_start_index..].sort_unstable_by(comparators::ByGeneratedTail::compare); + } + + mappings.by_generated = by_generated; + Ok(mappings) +} diff --git a/wasm-mappings/tests/quickcheck.rs b/wasm-mappings/tests/quickcheck.rs new file mode 100644 index 00000000..08f03a4f --- /dev/null +++ b/wasm-mappings/tests/quickcheck.rs @@ -0,0 +1,597 @@ +#[macro_use] +extern crate quickcheck; +extern crate source_map_mappings; +extern crate vlq; + +use quickcheck::{Arbitrary, Gen}; +use source_map_mappings::{Bias, Error}; +use std::cmp::Ordering; +use std::fmt; +use std::i64; +use std::iter; +use std::marker::PhantomData; + +trait VlqRange: 'static + Send + Copy + Clone + fmt::Debug + fmt::Display { + fn low() -> i64; + fn high() -> i64; +} + +#[derive(Copy, Clone, Debug)] +struct Vlq(i64, PhantomData); + +impl Arbitrary for Vlq +where + R: VlqRange, +{ + fn arbitrary(g: &mut G) -> Self { + Vlq(g.gen_range(R::low(), R::high()), PhantomData) + } + + fn shrink(&self) -> Box> { + Box::new(self.0.shrink().map(|x| Vlq(x, PhantomData))) + } +} + +impl fmt::Display for Vlq { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut v = vec![]; + vlq::encode(self.0, &mut v).unwrap(); + write!(f, "{}", String::from_utf8_lossy(&v)) + } +} + +#[derive(Clone, Debug)] +enum Mapping { + Generated { + generated_column: Vlq, + }, + Original { + generated_column: Vlq, + source: Vlq, + original_line: Vlq, + original_column: Vlq, + }, + OriginalWithName { + generated_column: Vlq, + source: Vlq, + original_line: Vlq, + original_column: Vlq, + name: Vlq, + }, +} + +impl Arbitrary for Mapping +where + R: VlqRange, +{ + fn arbitrary(g: &mut G) -> Self { + match g.gen_range(0, 3) { + 0 => Mapping::Generated { + generated_column: Vlq::::arbitrary(g), + }, + 1 => Mapping::Original { + generated_column: Vlq::::arbitrary(g), + source: Vlq::::arbitrary(g), + original_line: Vlq::::arbitrary(g), + original_column: Vlq::::arbitrary(g), + }, + 2 => Mapping::OriginalWithName { + generated_column: Vlq::::arbitrary(g), + source: Vlq::::arbitrary(g), + original_line: Vlq::::arbitrary(g), + original_column: Vlq::::arbitrary(g), + name: Vlq::::arbitrary(g), + }, + _ => unreachable!(), + } + } + + fn shrink(&self) -> Box> { + match *self { + Mapping::Generated { generated_column } => Box::new( + generated_column + .shrink() + .map(|generated_column| Mapping::Generated { generated_column }), + ), + Mapping::Original { + generated_column, + source, + original_line, + original_column, + } => { + let shrunkens = generated_column.shrink().zip( + source + .shrink() + .zip(original_line.shrink().zip(original_column.shrink())), + ); + let shrunkens = shrunkens.map( + move |(generated_column, (source, (original_line, original_column)))| { + Mapping::Original { + generated_column, + source, + original_line, + original_column, + } + }, + ); + + let generated = Mapping::Generated { generated_column }; + Box::new(iter::once(generated).chain(shrunkens)) + } + Mapping::OriginalWithName { + generated_column, + source, + original_line, + original_column, + name, + } => { + let shrunkens = generated_column.shrink().zip( + source.shrink().zip( + original_line + .shrink() + .zip(original_column.shrink().zip(name.shrink())), + ), + ); + let shrunkens = shrunkens.map( + move |( + generated_column, + (source, (original_line, (original_column, name))), + )| { + Mapping::OriginalWithName { + generated_column, + source, + original_line, + original_column, + name, + } + }, + ); + + let generated = Mapping::Generated { generated_column }; + let original = Mapping::Original { + generated_column, + source, + original_line, + original_column, + }; + Box::new( + iter::once(generated) + .chain(iter::once(original)) + .chain(shrunkens), + ) + } + } + } +} + +impl fmt::Display for Mapping { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Mapping::Generated { generated_column } => generated_column.fmt(f), + Mapping::Original { + generated_column, + source, + original_line, + original_column, + } => { + generated_column.fmt(f)?; + source.fmt(f)?; + original_line.fmt(f)?; + original_column.fmt(f) + } + Mapping::OriginalWithName { + generated_column, + source, + original_line, + original_column, + name, + } => { + generated_column.fmt(f)?; + source.fmt(f)?; + original_line.fmt(f)?; + original_column.fmt(f)?; + name.fmt(f) + } + } + } +} + +#[derive(Clone, Debug)] +struct GeneratedLine(Vec>); + +impl Arbitrary for GeneratedLine +where + R: VlqRange, +{ + fn arbitrary(g: &mut G) -> Self { + GeneratedLine(Vec::arbitrary(g)) + } + + fn shrink(&self) -> Box> { + Box::new(self.0.shrink().map(|v| GeneratedLine(v))) + } +} + +impl fmt::Display for GeneratedLine { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut needs_comma = false; + for m in &self.0 { + if needs_comma { + write!(f, ",")?; + } + m.fmt(f)?; + needs_comma = true; + } + Ok(()) + } +} + +#[derive(Clone, Debug)] +struct Mappings(Vec>); + +impl Arbitrary for Mappings +where + R: VlqRange, +{ + fn arbitrary(g: &mut G) -> Self { + Mappings(Vec::arbitrary(g)) + } + + fn shrink(&self) -> Box> { + Box::new(self.0.shrink().map(|v| Mappings(v))) + } +} + +impl fmt::Display for Mappings { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut needs_semi = false; + for line in &self.0 { + if needs_semi { + write!(f, ";")?; + } + line.fmt(f)?; + needs_semi = true; + } + Ok(()) + } +} + +#[derive(Copy, Clone, Debug)] +struct FullRange; + +impl fmt::Display for FullRange { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +impl VlqRange for FullRange { + fn low() -> i64 { + i64::MIN + } + fn high() -> i64 { + i64::MAX + } +} + +#[derive(Copy, Clone, Debug)] +struct SmallPositives; + +impl fmt::Display for SmallPositives { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +impl VlqRange for SmallPositives { + fn low() -> i64 { + 0 + } + fn high() -> i64 { + 5 + } +} + +quickcheck! { + fn parse_without_panicking(mappings: Mappings) -> () { + let mappings_string = mappings.to_string(); + let _ = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes()); + } + + fn parse_valid_mappings(mappings: Mappings) -> Result<(), Error> { + let mappings_string = mappings.to_string(); + source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + Ok(()) + } + + fn compute_column_spans(mappings: Mappings) -> Result<(), Error> { + let mappings_string = mappings.to_string(); + let mut mappings = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + + // Can compute column spans without panicking. + mappings.compute_column_spans(); + + // And those column spans make sense. + for window in mappings.by_generated_location().windows(2) { + let this_mapping = &window[0]; + let next_mapping = &window[1]; + if this_mapping.generated_line == next_mapping.generated_line { + assert_eq!(this_mapping.last_generated_column.unwrap(), next_mapping.generated_column); + } else { + assert!(this_mapping.last_generated_column.is_none()); + } + } + + Ok(()) + } + + fn original_location_for( + mappings: Mappings, + line: u32, + col: u32, + lub: bool + ) -> Result<(), Error> { + let mappings_string = mappings.to_string(); + let mappings = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + if mappings.by_generated_location().is_empty() { + return Ok(()); + } + + // To make this more useful, wrap `line` and `col` around the maximum + // line and column in the mappings respectively. + let max_line = mappings.by_generated_location() + .iter() + .map(|m| m.generated_line) + .max() + .unwrap(); + let max_col = mappings.by_generated_location() + .iter() + .map(|m| m.generated_column) + .max() + .unwrap(); + let line = line % (max_line + 1); + let col = col % (max_col + 1); + + let bias = if lub { + Bias::LeastUpperBound + } else { + Bias::GreatestLowerBound + }; + + // If we find a mapping, then it should either be an exact match or it + // should have the proper ordering relation to our query line/column + // based on the given bias. + if let Some(mapping) = mappings.original_location_for(line, col, bias) { + let found_line = mapping.generated_line; + let found_col = mapping.generated_column; + match line.cmp(&found_line).then(col.cmp(&found_col)) { + Ordering::Equal => {} + Ordering::Greater if bias == Bias::GreatestLowerBound => {} + Ordering::Less if bias == Bias::LeastUpperBound => {} + _ => panic!( + "Found bad location {{ line = {}, col = {} }} when \ + searching for {{ line = {}, col = {} }} with bias {:?}", + found_line, + found_col, + line, + col, + bias + ), + } + return Ok(()) + } + + // If we didn't get any result, then every mapping should not match our + // query, and should additionally be on the opposite side of ordering + // from our requested bias. + for m in mappings.by_generated_location().iter() { + match m.generated_line.cmp(&line).then(m.generated_column.cmp(&col)) { + Ordering::Equal => panic!("found matching mapping when we returned none"), + Ordering::Less => { + assert_eq!(bias, Bias::LeastUpperBound); + } + Ordering::Greater => { + assert_eq!(bias, Bias::GreatestLowerBound); + } + } + } + + Ok(()) + } + + fn original_mappings_have_original( + mappings: Mappings + ) -> Result { + let mappings_string = mappings.to_string(); + let mut mappings = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + Ok(mappings.by_original_location().all(|m| m.original.as_ref().is_some())) + } + + fn generated_location_for( + mappings: Mappings, + source: u32, + line: u32, + col: u32, + lub: bool + ) -> Result<(), Error> { + let mappings_string = mappings.to_string(); + let mut mappings = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + if !mappings.by_generated_location().iter().any(|m| m.original.is_some()) { + return Ok(()); + } + + // To make this more useful, wrap `source`, `line`, and `col` around the + // maximums. + let max_source = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().source) + .max() + .unwrap(); + let max_line = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().original_line) + .max() + .unwrap(); + let max_col = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().original_column) + .max() + .unwrap(); + let source = source % (max_source + 1); + let line = line % (max_line + 1); + let col = col % (max_col + 1); + + let bias = if lub { + Bias::LeastUpperBound + } else { + Bias::GreatestLowerBound + }; + + // If we find a mapping, then it should either be an exact match or it + // should have the proper ordering relation to our query line/column + // based on the given bias. + if let Some(mapping) = mappings.generated_location_for(source, line, col, bias) { + let found_source = mapping.original.as_ref().unwrap().source; + let found_line = mapping.original.as_ref().unwrap().original_line; + let found_col = mapping.original.as_ref().unwrap().original_column; + + let order = source.cmp(&found_source) + .then(line.cmp(&found_line)) + .then(col.cmp(&found_col)); + + match order { + Ordering::Equal => {} + Ordering::Greater if bias == Bias::GreatestLowerBound => {} + Ordering::Less if bias == Bias::LeastUpperBound => {} + _ => panic!( + "Found bad location {{ line = {}, col = {} }} when \ + searching for {{ line = {}, col = {} }} with bias {:?}", + found_line, + found_col, + line, + col, + bias + ), + } + return Ok(()) + } + + // If we didn't get any result, then every mapping should not match our + // query, and should additionally be on the opposite side of ordering + // from our requested bias. + for m in mappings.by_original_location() { + let m_orig = m.original.as_ref().unwrap(); + let m_source = m_orig.source; + let m_line = m_orig.original_line; + let m_col = m_orig.original_column; + + let order = m_source.cmp(&source) + .then(m_line.cmp(&line)) + .then(m_col.cmp(&col)); + + match order { + Ordering::Equal => panic!("found matching mapping when we returned none"), + Ordering::Less => { + assert_eq!(bias, Bias::LeastUpperBound); + } + Ordering::Greater => { + assert_eq!(bias, Bias::GreatestLowerBound); + } + } + } + + Ok(()) + } + + fn all_generated_locations_for( + mappings: Mappings, + source: u32, + line: u32, + col: Option + ) -> Result<(), Error> { + let mappings_string = mappings.to_string(); + let mut mappings = source_map_mappings::parse_mappings::<()>(mappings_string.as_bytes())?; + if !mappings.by_generated_location().iter().any(|m| m.original.is_some()) { + return Ok(()); + } + + let max_source = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().source) + .max() + .unwrap(); + let max_line = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().original_line) + .max() + .unwrap(); + let max_col = mappings.by_original_location() + .map(|m| m.original.as_ref().unwrap().original_column) + .max() + .unwrap(); + let source = source % (max_source + 1); + let mut line = line % (max_line + 1); + let mut col = if let Some(col) = col { + Some(col % (max_col + 1)) + } else { + None + }; + + let mut count = 0; + { + let locations = mappings.all_generated_locations_for(source, line, col); + + for (idx, m) in locations.into_iter().enumerate() { + count += 1; + + let m_orig = m.original.as_ref().unwrap(); + + // `all_generated_locations_for` does fuzzy searching: it will + // slide down to the next original line if there are no mappings + // on the queried line. Ditto for columns. This is to match + // mozilla/source-map's behavior. + if idx == 0 { + if m_orig.original_line != line { + assert!(m_orig.original_line > line); + line = m_orig.original_line; + } + if let Some(c) = col { + if c != m_orig.original_column { + col = Some(m_orig.original_column); + } + } + } + + assert_eq!( + m_orig.original_line, + line, + "result location's line is our query's line", + ); + + if let Some(col) = col { + assert_eq!( + m_orig.original_column, + col, + "result location's column is our query's column", + ); + } + } + } + + assert_eq!( + count, + mappings.by_original_location() + .filter(|m| { + let m_orig = m.original.as_ref().unwrap(); + if m_orig.source != source || m_orig.original_line != line { + return false; + } + if let Some(col) = col { + if m_orig.original_column != col { + return false; + } + } + true + }) + .count(), + "the iterator should find the right number of results" + ); + + Ok(()) + } +} diff --git a/wasm-mappings/tests/tests.rs b/wasm-mappings/tests/tests.rs new file mode 100644 index 00000000..16fc3b07 --- /dev/null +++ b/wasm-mappings/tests/tests.rs @@ -0,0 +1,427 @@ +extern crate source_map_mappings; + +use source_map_mappings::{parse_mappings, Bias, Mapping, Mappings, OriginalLocation}; + +#[test] +fn parse_empty_mappings() { + let mut mappings = parse_mappings::<()>(&[]).expect("should parse OK"); + assert!(mappings.by_generated_location().is_empty()); + assert_eq!(mappings.by_original_location().count(), 0); +} + +#[test] +fn invalid_mappings() { + assert!(parse_mappings::<()>(b"...").is_err()); +} + +// From mozilla/source-map's test/util.js `exports.testMap`. +const TEST_MAPPINGS: &'static [u8] = + b"CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA"; + +#[test] +fn can_parse_test_mappings_ok() { + parse_mappings::<()>(TEST_MAPPINGS).unwrap(); +} + +fn assert_generated_location_for( + mappings: &mut Mappings, + source: u32, + original_line: u32, + original_column: u32, + bias: Bias, + expected: Option, +) { + let actual = mappings.generated_location_for(source, original_line, original_column, bias); + assert_eq!(actual, expected.as_ref()); +} + +fn assert_original_location_for( + mappings: &mut Mappings, + generated_line: u32, + generated_column: u32, + bias: Bias, + expected: Option, +) { + let actual = mappings.original_location_for(generated_line, generated_column, bias); + assert_eq!(actual, expected.as_ref()); +} + +fn assert_bidirectional(mappings: &mut Mappings, mapping: Mapping) { + let orig = mapping.original.as_ref().unwrap(); + for bias in &[Bias::GreatestLowerBound, Bias::LeastUpperBound] { + assert_generated_location_for( + mappings, + orig.source, + orig.original_line, + orig.original_column, + *bias, + Some(mapping.clone()), + ); + + assert_original_location_for( + mappings, + mapping.generated_line, + mapping.generated_column, + *bias, + Some(mapping.clone()), + ); + } +} + +#[test] +fn test_mapping_back_exactly() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS).unwrap(); + + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 1, + last_generated_column: Some(5), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 1, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 5, + last_generated_column: Some(9), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 5, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 9, + last_generated_column: Some(18), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 11, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 18, + last_generated_column: Some(21), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 21, + name: Some(0), + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 21, + last_generated_column: Some(28), + original: Some(OriginalLocation { + source: 0, + original_line: 1, + original_column: 3, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 28, + last_generated_column: Some(32), + original: Some(OriginalLocation { + source: 0, + original_line: 1, + original_column: 10, + name: Some(1), + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 0, + generated_column: 32, + last_generated_column: None, + original: Some(OriginalLocation { + source: 0, + original_line: 1, + original_column: 14, + name: Some(0), + }), + }, + ); + + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 1, + last_generated_column: Some(5), + original: Some(OriginalLocation { + source: 1, + original_line: 0, + original_column: 1, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 5, + last_generated_column: Some(9), + original: Some(OriginalLocation { + source: 1, + original_line: 0, + original_column: 5, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 9, + last_generated_column: Some(18), + original: Some(OriginalLocation { + source: 1, + original_line: 0, + original_column: 11, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 18, + last_generated_column: Some(21), + original: Some(OriginalLocation { + source: 1, + original_line: 0, + original_column: 21, + name: Some(2), + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 21, + last_generated_column: Some(28), + original: Some(OriginalLocation { + source: 1, + original_line: 1, + original_column: 3, + name: None, + }), + }, + ); + assert_bidirectional( + &mut mappings, + Mapping { + generated_line: 1, + generated_column: 28, + last_generated_column: None, + original: Some(OriginalLocation { + source: 1, + original_line: 1, + original_column: 10, + name: Some(2), + }), + }, + ); +} + +// From mozilla/source-map's test/test-source-map-consumer.js's "test +// allGeneratedPositionsFor for line" test case. +const TEST_MAPPINGS_2: &'static [u8] = b";EAAC,ACAA;EACA,CAAC;EACD"; + +#[test] +fn test_all_generated_locations_for_some_line() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS_2).unwrap(); + + let mappings_on_source_1_line_1: Vec<_> = mappings + .all_generated_locations_for(1, 1, None) + .cloned() + .collect(); + + assert_eq!( + mappings_on_source_1_line_1, + vec![ + Mapping { + generated_line: 2, + generated_column: 2, + last_generated_column: Some(3), + original: Some(OriginalLocation { + source: 1, + original_line: 1, + original_column: 1, + name: None, + }), + }, + Mapping { + generated_line: 2, + generated_column: 3, + last_generated_column: None, + original: Some(OriginalLocation { + source: 1, + original_line: 1, + original_column: 2, + name: None, + }), + }, + ] + ); +} + +// Taken from mozilla/source-map's test/test-source-map-consumer.js's "test +// allGeneratedPositionsFor for line fuzzy" +const TEST_MAPPINGS_3: &'static [u8] = b";EAAC,ACAA;;EAEA"; + +#[test] +fn test_all_generated_locations_for_line_fuzzy() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS_3).unwrap(); + + let mappings_on_source_1_line_1: Vec<_> = mappings + .all_generated_locations_for(1, 1, None) + .cloned() + .collect(); + + assert_eq!( + mappings_on_source_1_line_1, + vec![ + Mapping { + generated_line: 3, + generated_column: 2, + last_generated_column: None, + original: Some(OriginalLocation { + source: 1, + original_line: 2, + original_column: 1, + name: None, + }), + }, + ] + ); +} + +// Taken from mozilla/source-map's test/test-source-map-consumer.js's "test +// allGeneratedPositionsFor for column". +const TEST_MAPPINGS_4: &'static [u8] = b"EAAC,CAAA"; + +#[test] +fn test_all_generated_locations_for_column() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS_4).unwrap(); + + let mappings_on_source_0_line_0_column_1: Vec<_> = mappings + .all_generated_locations_for(0, 0, Some(1)) + .cloned() + .collect(); + + assert_eq!( + mappings_on_source_0_line_0_column_1, + vec![ + Mapping { + generated_line: 0, + generated_column: 2, + last_generated_column: Some(3), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 1, + name: None, + }), + }, + Mapping { + generated_line: 0, + generated_column: 3, + last_generated_column: None, + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 1, + name: None, + }), + }, + ] + ); +} + +#[test] +fn test_all_generated_locations_for_column_fuzzy() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS_4).unwrap(); + + let mappings_on_source_0_line_0_column_0: Vec<_> = mappings + .all_generated_locations_for(0, 0, Some(0)) + .cloned() + .collect(); + + assert_eq!( + mappings_on_source_0_line_0_column_0, + vec![ + Mapping { + generated_line: 0, + generated_column: 2, + last_generated_column: Some(3), + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 1, + name: None, + }), + }, + Mapping { + generated_line: 0, + generated_column: 3, + last_generated_column: None, + original: Some(OriginalLocation { + source: 0, + original_line: 0, + original_column: 1, + name: None, + }), + }, + ] + ); +} + +// From mozilla/source-map's test/test-source-map-consumer.js's "test +// allGeneratedPositionsFor for column on different line fuzzy". +const TEST_MAPPINGS_5: &'static [u8] = b";EACC,CAAA"; + +#[test] +fn test_all_generated_locations_for_column_on_different_line_fuzzy() { + let mut mappings = parse_mappings::<()>(TEST_MAPPINGS_5).unwrap(); + + let mappings_on_source_0_line_0_column_0: Vec<_> = mappings + .all_generated_locations_for(0, 0, Some(0)) + .cloned() + .collect(); + + assert!(mappings_on_source_0_line_0_column_0.is_empty()); +} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 65ffb502..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,20 +0,0 @@ -const path = require("path"); -const distDir = path.join(__dirname, "dist"); - -module.exports = [ - // Web build. - { - entry: "./source-map.js", - mode: "production", - output: { - path: distDir, - filename: "source-map.js", - library: "sourceMap", - libraryTarget: "umd", - }, - externals: [ - "fs", - "path", - ] - } -];