From 95fc51cc99f76fc77f1bbc678bd52f0268d18cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <33655937+jkoenig134@users.noreply.github.com> Date: Mon, 27 Sep 2021 08:19:56 +0200 Subject: [PATCH] Chore/initialize (#1) * chore: add dev-env * chore: add src * chore: add tests * chore: add package definition * chore: add eslint ignorePatterns * chore: bump libs * ci: add pipeline * ci: use npx for license-check * ci: run in browsertest image * chore: newline * chore: add scripts * chore: use test:ci * chore: simplify token usage * ci: use correct registry * chore: update package.json * chore: add test:local:node script --- .ci/build.sh | 9 + .ci/publish.sh | 5 + .ci/test.sh | 4 + .ci/writeBuildInformation.sh | 13 + .eslintrc | 15 + .github/workflows/publish.yml | 19 + .github/workflows/test.yml | 16 + .gitignore | 5 + .prettierignore | 4 + .prettierrc | 15 + .vscode/settings.json | 36 + README_Dev.md | 62 + nbt.json | 13 + package-lock.json | 14405 ++++++++++++++++ package.json | 68 + src/Serializable.ts | 114 + src/SerializableAsync.ts | 146 + src/SerializableBase.ts | 274 + src/ServalBuildInformation.ts | 18 + src/errors.ts | 42 + src/index.ts | 18 + src/interfaces.ts | 13 + src/parsing/Parser.ts | 440 + src/parsing/ParsingError.ts | 26 + src/reflection/ReflectProperty.ts | 59 + src/reflection/globals.ts | 33 + src/serialization/Serialize.ts | 164 + src/serialization/SerializeParameter.ts | 87 + src/validation/Validate.ts | 234 + src/validation/ValidateGlobals.ts | 55 + src/validation/ValidateInterfaces.ts | 97 + src/validation/ValidationError.ts | 26 + src/validation/Validator.ts | 232 + src/wrapper/JSONWrapper.ts | 22 + src/wrapper/JSONWrapperAsync.ts | 22 + test/data/consumption/Attribute.ts | 26 + test/data/consumption/BetterAttribute.ts | 17 + test/data/consumption/Draft.ts | 39 + .../data/consumption/RelationshipAttribute.ts | 18 + .../RelationshipAttributeHistoryItem.ts | 31 + test/data/consumption/RelationshipMetadata.ts | 39 + test/data/core/CachedMessage.ts | 51 + test/data/core/Certificate.ts | 44 + test/data/core/CoreSerializable.ts | 6 + test/data/core/CoreSerializableAsync.ts | 6 + test/data/core/CoreSynchronizable.ts | 10 + test/data/core/Mail.ts | 41 + test/data/core/Message.ts | 63 + test/data/core/MessageContent.ts | 7 + test/data/core/MessageEnvelopeRecipient.ts | 24 + test/data/core/TokenContent.ts | 7 + test/data/core/TokenContentGeneric.ts | 21 + .../core/TokenContentRelationshipTemplate.ts | 28 + test/data/core/TokenContentString.ts | 21 + test/data/core/types/CoreAddress.ts | 44 + test/data/core/types/CoreDate.ts | 62 + test/data/core/types/CoreId.ts | 39 + test/data/crypto/CoreBuffer.ts | 51 + test/data/crypto/CryptoCipher.ts | 76 + test/data/crypto/CryptoSecretKey.ts | 67 + test/data/crypto/CryptoSerializableAsync.ts | 8 + test/data/crypto/CryptoSignature.ts | 93 + test/index.ts | 74 + test/performance.ts | 122 + .../async/ArrayInheritanceAsync.test.ts | 192 + test/serialize/async/InheritanceAsync.test.ts | 719 + .../async/SerializeAsyncAnyProperty.test.ts | 39 + .../async/SerializeAsyncClassProperty.test.ts | 329 + ...erializeAsyncEnforceStringProperty.test.ts | 73 + .../SerializeAsyncGenericProperty.test.ts | 80 + .../async/SerializeAsyncMultiType.test.ts | 214 + .../async/SerializeAsyncTypedArray.test.ts | 141 + .../async/SerializeAsyncWrapper.test.ts | 283 + .../async/SerializeOnlyAsync.test.ts | 29 + test/serialize/sync/ArrayInheritance.test.ts | 192 + test/serialize/sync/Inheritance.test.ts | 670 + .../sync/SerializeAnyProperty.test.ts | 39 + .../sync/SerializeClassProperty.test.ts | 335 + .../SerializeEnforceStringProperty.test.ts | 74 + .../sync/SerializeGenericProperty.test.ts | 70 + .../serialize/sync/SerializeMultiType.test.ts | 193 + test/serialize/sync/SerializeOnly.test.ts | 29 + .../sync/SerializeTypedArray.test.ts | 140 + test/serialize/sync/SerializeWrapper.test.ts | 280 + test/testUtil.ts | 33 + test/tsconfig.json | 27 + test/usage/Core.test.ts | 35 + test/validate/ValidateAnyProperty.test.ts | 236 + test/validate/ValidateGenericProperty.test.ts | 41 + ...idatePropertyAnnotatedWithTypeTest.test.ts | 44 + tsconfig.json | 27 + tsconfig.test.json | 26 + ui5.yaml | 9 + webpack.config.js | 28 + webpack.min.config.js | 40 + webpack.test.config.js | 28 + 96 files changed, 22641 insertions(+) create mode 100644 .ci/build.sh create mode 100644 .ci/publish.sh create mode 100644 .ci/test.sh create mode 100755 .ci/writeBuildInformation.sh create mode 100644 .eslintrc create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .vscode/settings.json create mode 100644 README_Dev.md create mode 100644 nbt.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/Serializable.ts create mode 100644 src/SerializableAsync.ts create mode 100644 src/SerializableBase.ts create mode 100644 src/ServalBuildInformation.ts create mode 100644 src/errors.ts create mode 100644 src/index.ts create mode 100644 src/interfaces.ts create mode 100644 src/parsing/Parser.ts create mode 100644 src/parsing/ParsingError.ts create mode 100644 src/reflection/ReflectProperty.ts create mode 100644 src/reflection/globals.ts create mode 100644 src/serialization/Serialize.ts create mode 100644 src/serialization/SerializeParameter.ts create mode 100644 src/validation/Validate.ts create mode 100644 src/validation/ValidateGlobals.ts create mode 100644 src/validation/ValidateInterfaces.ts create mode 100644 src/validation/ValidationError.ts create mode 100644 src/validation/Validator.ts create mode 100644 src/wrapper/JSONWrapper.ts create mode 100644 src/wrapper/JSONWrapperAsync.ts create mode 100644 test/data/consumption/Attribute.ts create mode 100644 test/data/consumption/BetterAttribute.ts create mode 100644 test/data/consumption/Draft.ts create mode 100644 test/data/consumption/RelationshipAttribute.ts create mode 100644 test/data/consumption/RelationshipAttributeHistoryItem.ts create mode 100644 test/data/consumption/RelationshipMetadata.ts create mode 100644 test/data/core/CachedMessage.ts create mode 100644 test/data/core/Certificate.ts create mode 100644 test/data/core/CoreSerializable.ts create mode 100644 test/data/core/CoreSerializableAsync.ts create mode 100644 test/data/core/CoreSynchronizable.ts create mode 100644 test/data/core/Mail.ts create mode 100644 test/data/core/Message.ts create mode 100644 test/data/core/MessageContent.ts create mode 100644 test/data/core/MessageEnvelopeRecipient.ts create mode 100644 test/data/core/TokenContent.ts create mode 100644 test/data/core/TokenContentGeneric.ts create mode 100644 test/data/core/TokenContentRelationshipTemplate.ts create mode 100644 test/data/core/TokenContentString.ts create mode 100644 test/data/core/types/CoreAddress.ts create mode 100644 test/data/core/types/CoreDate.ts create mode 100644 test/data/core/types/CoreId.ts create mode 100644 test/data/crypto/CoreBuffer.ts create mode 100644 test/data/crypto/CryptoCipher.ts create mode 100644 test/data/crypto/CryptoSecretKey.ts create mode 100644 test/data/crypto/CryptoSerializableAsync.ts create mode 100644 test/data/crypto/CryptoSignature.ts create mode 100644 test/index.ts create mode 100644 test/performance.ts create mode 100644 test/serialize/async/ArrayInheritanceAsync.test.ts create mode 100644 test/serialize/async/InheritanceAsync.test.ts create mode 100644 test/serialize/async/SerializeAsyncAnyProperty.test.ts create mode 100644 test/serialize/async/SerializeAsyncClassProperty.test.ts create mode 100644 test/serialize/async/SerializeAsyncEnforceStringProperty.test.ts create mode 100644 test/serialize/async/SerializeAsyncGenericProperty.test.ts create mode 100644 test/serialize/async/SerializeAsyncMultiType.test.ts create mode 100644 test/serialize/async/SerializeAsyncTypedArray.test.ts create mode 100644 test/serialize/async/SerializeAsyncWrapper.test.ts create mode 100644 test/serialize/async/SerializeOnlyAsync.test.ts create mode 100644 test/serialize/sync/ArrayInheritance.test.ts create mode 100644 test/serialize/sync/Inheritance.test.ts create mode 100644 test/serialize/sync/SerializeAnyProperty.test.ts create mode 100644 test/serialize/sync/SerializeClassProperty.test.ts create mode 100644 test/serialize/sync/SerializeEnforceStringProperty.test.ts create mode 100644 test/serialize/sync/SerializeGenericProperty.test.ts create mode 100644 test/serialize/sync/SerializeMultiType.test.ts create mode 100644 test/serialize/sync/SerializeOnly.test.ts create mode 100644 test/serialize/sync/SerializeTypedArray.test.ts create mode 100644 test/serialize/sync/SerializeWrapper.test.ts create mode 100644 test/testUtil.ts create mode 100644 test/tsconfig.json create mode 100644 test/usage/Core.test.ts create mode 100644 test/validate/ValidateAnyProperty.test.ts create mode 100644 test/validate/ValidateGenericProperty.test.ts create mode 100644 test/validate/ValidatePropertyAnnotatedWithTypeTest.test.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.test.json create mode 100644 ui5.yaml create mode 100644 webpack.config.js create mode 100644 webpack.min.config.js create mode 100644 webpack.test.config.js diff --git a/.ci/build.sh b/.ci/build.sh new file mode 100644 index 0000000..fb434bd --- /dev/null +++ b/.ci/build.sh @@ -0,0 +1,9 @@ +set -e +set -x + +npm ci +npm run lint:prettier +npm run lint:eslint +npx license-check +npm audit +npm run build:ci diff --git a/.ci/publish.sh b/.ci/publish.sh new file mode 100644 index 0000000..9936aeb --- /dev/null +++ b/.ci/publish.sh @@ -0,0 +1,5 @@ +set -e +set -x + +npm set //registry.npmjs.org/:_authToken=${NPM_TOKEN} +npm publish diff --git a/.ci/test.sh b/.ci/test.sh new file mode 100644 index 0000000..d42350d --- /dev/null +++ b/.ci/test.sh @@ -0,0 +1,4 @@ +set -e +set -x + +npm run test:ci diff --git a/.ci/writeBuildInformation.sh b/.ci/writeBuildInformation.sh new file mode 100755 index 0000000..8126c8c --- /dev/null +++ b/.ci/writeBuildInformation.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -e + +if ! command -v jq &>/dev/null; then + echo "jq could not be found" + exit 1 +fi + +sed -i "s/{{dependencies}}/$(jq .dependencies package.json -cr)/" ./dist/ServalBuildInformation.js +sed -i "s/{{version}}/$(jq .version package.json -cr)/" ./dist/ServalBuildInformation.js +sed -i "s/{{build}}/$BITBUCKET_BUILD_NUMBER/" ./dist/ServalBuildInformation.js +sed -i "s/{{commit}}/$(git rev-parse HEAD)/" ./dist/ServalBuildInformation.js +sed -i "s/{{date}}/$(date -u --iso-8601=seconds)/" ./dist/ServalBuildInformation.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..e796fd5 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,15 @@ +{ + "ignorePatterns": ["/*", "!/src", "!/test"], + "extends": ["@js-soft/ts", "@js-soft/ts/mocha"], + "parserOptions": { + "project": ["tsconfig.json", "test/tsconfig.json"] + }, + "rules": { + "jest/expect-expect": [ + "error", + { + "assertFunctionNames": ["expect", "expectValid*", "expectThrows*"] + } + ] + } +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..286c799 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,19 @@ +name: Publish + +on: + push: + branches: + - main + +jobs: + publish-npm: + runs-on: ubuntu-latest + container: jssoft/node_browsertests + steps: + - uses: actions/checkout@v2 + - run: apt-get update && apt-get install jq -y + - run: bash .ci/build.sh + - run: bash .ci/test.sh + - run: bash .ci/publish.sh + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..eb23725 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,16 @@ +name: Test + +on: + push: + branches-ignore: + - main + +jobs: + test: + runs-on: ubuntu-latest + container: jssoft/node_browsertests + steps: + - uses: actions/checkout@v2 + - run: apt-get update && apt-get install jq -y + - run: bash .ci/build.sh + - run: bash .ci/test.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac749d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist-test +dist +lib-web +chromedriver.log diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b6b65e1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +dist +dist-test +lib-web +node_modules diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..50865e6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,15 @@ +{ + "endOfLine": "lf", + "printWidth": 120, + "tabWidth": 4, + "trailingComma": "none", + "semi": false, + "overrides": [ + { + "files": ["*.yaml", "*.yml"], + "options": { + "tabWidth": 2 + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9eb64d0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,36 @@ +{ + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "files.autoSave": "off", + "editor.codeActionsOnSave": { + "source.organizeImports": true + }, + "files.eol": "\n", + "todo-tree.filtering.excludeGlobs": [ + "**/node_modules/**", + "**/dist/**", + "**/dist-test/**", + "**/lib-web/**", + "**/*.min.*", + "**/*.map" + ], + "todo-tree.general.tags": ["TODO:"] +} diff --git a/README_Dev.md b/README_Dev.md new file mode 100644 index 0000000..0d9b321 --- /dev/null +++ b/README_Dev.md @@ -0,0 +1,62 @@ +# Development Guide + +Install all dependencies and build/test the current version with these commands: + +``` +npm i +npm run bt +``` + +## Build and Test + +To run all tests and required builds, use the shorthand command `bt` to build and test all assets. `bt` is first running a NodeJS test and afterwards bundling the browser assets to execute the browser tests on them. + +## Build Setup and Assets + +This library is built with `tsc` and `webpack` and outputs the following assets: + +- `/dist` folder - for further development in a non-browser environment (e.g. NodeJS/TypeScript context) +- `tsserval.js` - the uncompressed browser javascript source +- `tsserval.min.js` - the compressed browser javascript source +- Additional files (map files, licenses, ...) + +## Build Scripts + +Various build scripts are available over the `npm run` commands: + +- `bt` builds all assets and runs all tests in a smart order (without doing too many things if tests break) +- `build` compiles all sources, tests to /dist and packs them browser-friendly to /lib-web + - `build:node` compiles all TypeScript sources via `tsc` from /src to /dist and checks circular dependencies on /dist + - `build:test` compiles all TypeScript tests via `tsc` from /test to /dist-test + - `bundle` creates browser-friendly assets + - `bundle:lib` bundles compiled distribution files to a browser-friendly asset via `webpack` from /dist to /lib-web (tsserval.js) + - `bundle:min` bundles compiled distribution files to a compressed/minified browser-friendly asset via `webpack` from /dist to /lib-web (tsserval.min.js) + - `bundle:test` bundles compiled test files to a browser-friendly form via `webpack` from /dist-test to /lib-web +- `build:ci` is meant as build command for the pipeline and effectively runs `build` with a step in between, which replaces the runtime version informations in the respective file + +## Test Setup + +Tests are written in TypeScript and executed in NodeJS and browser environments. + +- NodeJS tests are executed with the `mocha` testrunner and `node-ts` as TypeScript environment. Thus, running the NodeJS tests do not require a `build` step as `node-ts` is coping with the TypeScript compilation internally. +- Browser tests are executed with `bt-runner` which uses `chromedriver` to test the bundled assets in compressed and uncompressed variants within the browser environment. The browser tests do not automatically `bundle` new builds, thus a browser build must be triggered before the browser tests. + +## Test Scripts + +Various test scripts are available over the `npm run` commands: + +- `bt` builds all assets and runs all tests in a smart order (without doing too many things if tests break) +- `test` runs all tests, first NodeJS then browser environment + - `test:node` runs NodeJS tests with `node-ts` + - `test:web` runs the tests on a browser environment with `bt-runner` +- `test:server` runs a keep-alive version of `bt-runner` which can be used for debugging + +## Deployment + +Because of the `files` property within the `package.json`, only the respective build assets are published to the package registry. A license check is done before publishing it to the respective package registry. + +## Runtime Dependencies + +ts-serval only has only one runtime dependency so far, which is `reflect-metadata` to extract the metadata information out of the TypeScript compilation process and make it accessible in the runtime context. + +# Common Mistakes diff --git a/nbt.json b/nbt.json new file mode 100644 index 0000000..da6d112 --- /dev/null +++ b/nbt.json @@ -0,0 +1,13 @@ +{ + "testFolder": "./lib-web", + "runners": [ + { + "dependencies": ["tsserval.js", "tsserval.test.js"], + "globals": ["TSServal", "TSServalTest"] + }, + { + "dependencies": ["tsserval.min.js", "tsserval.test.js"], + "globals": ["TSServal", "TSServalTest"] + } + ] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..db37e17 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,14405 @@ +{ + "name": "@js-soft/ts-serval", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@js-soft/ts-serval", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@js-soft/eslint-config-ts": "1.3.3", + "@js-soft/license-check": "1.0.2", + "@types/chai": "^4.2.22", + "@types/mocha": "^9.0.0", + "@types/node": "^16.9.6", + "bt-runner": "^1.0.17", + "buffer": "^6.0.3", + "chai": "^4.3.4", + "eslint": "7.32.0", + "madge": "^5.0.1", + "mocha": "^9.1.1", + "prettier": "^2.4.1", + "terser-webpack-plugin": "5.2.4", + "ts-node": "^10.2.1", + "tsconfig-paths": "^3.11.0", + "typescript": "^4.4.3", + "webpack": "^5.53.0", + "webpack-cli": "^4.8.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", + "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", + "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@js-soft/eslint-config-ts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@js-soft/eslint-config-ts/-/eslint-config-ts-1.3.3.tgz", + "integrity": "sha512-A+6uBaBXP44rmRLG2rtrmAE8r4xLh7npFIXMwzxD32Y8TEJX3Qj2WaaoQA3TjedvANQUtWYr2QDpoNuKWC9aAA==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^4.31.1", + "@typescript-eslint/parser": "^4.31.1", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.7.2", + "eslint-plugin-jest": "^24.4.2", + "eslint-plugin-mocha": "^9.0.0" + }, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/@js-soft/license-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@js-soft/license-check/-/license-check-1.0.2.tgz", + "integrity": "sha512-r/JBeQsZ82WIoOjLueFNDdSa/7++6af+NlWuSSmmo9QJqeRjbDAYJnlG5ZXfdm0B4sk1S4gMf90WeTO7KtG83w==", + "dev": true, + "dependencies": { + "license-checker": "^25.0.1", + "yargs": "^17.2.0" + }, + "bin": { + "license-check": "bin/licenseCheck.js" + } + }, + "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/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.2.22", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", + "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", + "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.31.2", + "@typescript-eslint/scope-manager": "4.31.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", + "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", + "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", + "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", + "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", + "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", + "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz", + "integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==", + "dev": true, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz", + "integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==", + "dev": true, + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz", + "integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==", + "dev": true, + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "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/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.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/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", + "dev": true + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ast-module-types": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", + "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "dev": true + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "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/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/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/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "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/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", + "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001259", + "electron-to-chromium": "^1.3.846", + "escalade": "^3.1.1", + "nanocolors": "^0.1.5", + "node-releases": "^1.1.76" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bt-runner": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/bt-runner/-/bt-runner-1.0.17.tgz", + "integrity": "sha512-DhedhWeeNC4wtFXp/9eUPq8/rdUcTG+GNVWW5QxubOgJuOtoQ+iWGw7hStjOzqayGNVMsRR6NrJPmRNoILU5ng==", + "dev": true, + "dependencies": { + "chai": "^4.3.4", + "express": "^4.17.1", + "express-http-proxy": "^1.6.2", + "mocha": "^9.1.1", + "nightwatch": "^1.7.11", + "rimraf": "^3.0.2", + "yargs": "^17.1.1" + }, + "bin": { + "browsertest-runner": "dist/index.js", + "browsertest-runner-debug": "dist/index_debug.js" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001260", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001260.tgz", + "integrity": "sha512-Fhjc/k8725ItmrvW5QomzxLeojewxvqiYCKeFcfFEhut28IVLdpHU19dneOmltZQIE5HNbawj1HYD+1f2bM1Dg==", + "dev": true, + "dependencies": { + "nanocolors": "^0.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-nightwatch": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/chai-nightwatch/-/chai-nightwatch-0.4.1.tgz", + "integrity": "sha512-s2put5cFhG8Hw+6Po3R8QZ0ctsDmcaIh7+l9Fu3RcLCfosfQffT3mcFSq2jmXEQk0pmwo/PuXvYMO87MRlyqxg==", + "dev": true, + "dependencies": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/chai-nightwatch/node_modules/assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chai-nightwatch/node_modules/deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "dependencies": { + "type-detect": "0.1.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chai-nightwatch/node_modules/type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "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/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "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/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decomment": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.4.tgz", + "integrity": "sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw==", + "dev": true, + "dependencies": { + "esprima": "4.0.1" + }, + "engines": { + "node": ">=6.4", + "npm": ">=2.15" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "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/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/degenerator": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz", + "integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/degenerator/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/degenerator/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/dependency-tree": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-8.1.1.tgz", + "integrity": "sha512-bl5U16VQpaYxD0xvcnCH/dTctCiWnsVWymh9dNjbm4T00Hm21flu1VLnNueKCj7+3uusbcJhKKKtiWrpU0I+Nw==", + "dev": true, + "dependencies": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "filing-cabinet": "^3.0.0", + "precinct": "^8.0.0", + "typescript": "^3.9.7" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": "^10.13 || ^12 || >=14" + } + }, + "node_modules/dependency-tree/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/dependency-tree/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detective-amd": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.0.tgz", + "integrity": "sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw==", + "dev": true, + "dependencies": { + "ast-module-types": "^2.7.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^3.0.0", + "node-source-walk": "^4.0.0" + }, + "bin": { + "detective-amd": "bin/detective-amd.js" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-cjs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.1.tgz", + "integrity": "sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg==", + "dev": true, + "dependencies": { + "ast-module-types": "^2.4.0", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-es6": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.0.tgz", + "integrity": "sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ==", + "dev": true, + "dependencies": { + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-less": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/detective-less/-/detective-less-1.0.2.tgz", + "integrity": "sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA==", + "dev": true, + "dependencies": { + "debug": "^4.0.0", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-postcss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-5.0.0.tgz", + "integrity": "sha512-IBmim4GTEmZJDBOAoNFBskzNryTmYpBq+CQGghKnSGkoGWascE8iEo98yA+ZM4N5slwGjCr/NxCm+Kzg+q3tZg==", + "dev": true, + "dependencies": { + "debug": "^4.3.1", + "is-url": "^1.2.4", + "postcss": "^8.2.13", + "postcss-values-parser": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/detective-sass": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.1.tgz", + "integrity": "sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-scss": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.1.tgz", + "integrity": "sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-stylus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.0.tgz", + "integrity": "sha1-UK7n24uruZA4HwEMY/q7pbWOVM0=", + "dev": true + }, + "node_modules/detective-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.0.tgz", + "integrity": "sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "^4.8.2", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.7" + }, + "engines": { + "node": "^10.13 || >=12.0.0" + } + }, + "node_modules/detective-typescript/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/dotenv": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", + "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dev": true, + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.849", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.849.tgz", + "integrity": "sha512-RweyW60HPOqIcxoKTGr38Yvtf2aliSUqX8dB3e9geJ0Bno0YLjcOX5F7/DPVloBkJWaPZ7xOM1A0Yme2T1A34w==", + "dev": true + }, + "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/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-abstract": { + "version": "1.18.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", + "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==", + "dev": true + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "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-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "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/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-chai-expect": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", + "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + }, + "peerDependencies": { + "eslint": ">=2.0.0 <= 7.x" + } + }, + "node_modules/eslint-plugin-chai-friendly": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", + "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^4.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": ">= 4", + "eslint": ">=5" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.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-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/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "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/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "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/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-http-proxy": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.6.2.tgz", + "integrity": "sha512-soP7UXySFdLbeeMYL1foBkEoZj6HELq9BDAOCr1sLRpqjPaFruN5o6+bZeC+7U4USWIl4JMKEiIvTeKJ2WQdlQ==", + "dev": true, + "dependencies": { + "debug": "^3.0.1", + "es6-promise": "^4.1.1", + "raw-body": "^2.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/express-http-proxy/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "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/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "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-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "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": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "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/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/file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/filing-cabinet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.0.0.tgz", + "integrity": "sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw==", + "dev": true, + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^2.20.3", + "debug": "^4.3.1", + "decomment": "^0.9.3", + "enhanced-resolve": "^5.3.2", + "is-relative-path": "^1.0.2", + "module-definition": "^3.3.1", + "module-lookup-amd": "^7.0.0", + "resolve": "^1.19.0", + "resolve-dependency-path": "^2.0.0", + "sass-lookup": "^3.0.0", + "stylus-lookup": "^3.0.1", + "typescript": "^3.9.7" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/filing-cabinet/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/filing-cabinet/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "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": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "dependencies": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ftp/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ftp/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/get-amd-module-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz", + "integrity": "sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw==", + "dev": true, + "dependencies": { + "ast-module-types": "^2.3.2", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "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/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "node_modules/graphviz": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz", + "integrity": "sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==", + "dev": true, + "dependencies": { + "temp": "~0.4.0" + }, + "engines": { + "node": ">=0.6.8" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "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/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", + "integrity": "sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=", + "dev": true + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "dependencies": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/jake/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jake/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-worker": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz", + "integrity": "sha512-laB0ZVIBz+voh/QQy9dmUuuDsadixeerrKqyVpgPz+CCWiOYjOBabUXHIXZhsdvkWbLqSHbgkAHWl5cg24Q6RA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "bin": { + "license-checker": "bin/license-checker" + } + }, + "node_modules/license-checker/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/license-checker/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/license-checker/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/license-checker/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/license-checker/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/license-checker/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "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": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=", + "dev": true + }, + "node_modules/lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=", + "dev": true + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._baseclone": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", + "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=", + "dev": true, + "dependencies": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._baseassign": "^3.0.0", + "lodash._basefor": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "node_modules/lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=", + "dev": true + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "node_modules/lodash.clone": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz", + "integrity": "sha1-hGiMc9MrWpDKJWFpY/GJJSqZcEM=", + "dev": true, + "dependencies": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "dev": true + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "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/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/madge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/madge/-/madge-5.0.1.tgz", + "integrity": "sha512-krmSWL9Hkgub74bOjnjWRoFPAJvPwSG6Dbta06qhWOq6X/n/FPzO3ESZvbFYVIvG2g4UHXvCJN1b+RZLaSs9nA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.1", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.1", + "dependency-tree": "^8.1.1", + "detective-amd": "^3.1.0", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^5.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "graphviz": "0.0.9", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "precinct": "^8.1.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.7", + "typescript": "^3.9.5", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": "^10.13 || ^12 || >=14" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + } + }, + "node_modules/madge/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "dependencies": { + "mime-db": "1.49.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", + "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", + "dev": true + }, + "node_modules/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.23", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/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/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/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/mocha/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/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/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/module-definition": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.3.1.tgz", + "integrity": "sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A==", + "dev": true, + "dependencies": { + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.0.0" + }, + "bin": { + "module-definition": "bin/module-definition.js" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/module-lookup-amd": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz", + "integrity": "sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1", + "debug": "^4.1.0", + "glob": "^7.1.6", + "requirejs": "^2.3.5", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/module-lookup-amd/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "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/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanocolors": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz", + "integrity": "sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/nightwatch": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.7.11.tgz", + "integrity": "sha512-yV795EBXZ/myeoCvBtjC/QwvIprxF7SKh0XCeFnpoOtWXDb0yv+ATLRipKGfp+avyGtagqq38ucA4Uh6WPcnhQ==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "chai-nightwatch": "^0.4.0", + "ci-info": "^2.0.0", + "didyoumean": "^1.2.1", + "dotenv": "7.0.0", + "ejs": "^3.1.6", + "envinfo": "^7.5.1", + "lodash.clone": "3.0.3", + "lodash.defaultsdeep": "^4.6.1", + "lodash.merge": "^4.6.2", + "minimatch": "3.0.4", + "minimist": "^1.2.5", + "mkpath": "1.0.0", + "mocha": "6.2.3", + "ora": "^4.0.3", + "proxy-agent": "^5.0.0", + "request": "^2.88.2", + "request-promise": "^4.2.5", + "semver": "^6.3.0", + "strip-ansi": "^6.0.0" + }, + "bin": { + "nightwatch": "bin/nightwatch" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "chromedriver": "*", + "geckodriver": "*" + }, + "peerDependenciesMeta": { + "chromedriver": { + "optional": true + }, + "geckodriver": { + "optional": true + } + } + }, + "node_modules/nightwatch/node_modules/ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/nightwatch/node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/nightwatch/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/nightwatch/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nightwatch/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nightwatch/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/nightwatch/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/nightwatch/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nightwatch/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/nightwatch/node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nightwatch/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/nightwatch/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/nightwatch/node_modules/mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "dev": true, + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/nightwatch/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/nightwatch/node_modules/ora": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", + "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nightwatch/node_modules/ora/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/nightwatch/node_modules/ora/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nightwatch/node_modules/ora/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/nightwatch/node_modules/ora/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/nightwatch/node_modules/ora/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/nightwatch/node_modules/ora/node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/ora/node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/node_modules/ora/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/nightwatch/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nightwatch/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nightwatch/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/nightwatch/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/string-width/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nightwatch/node_modules/supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/nightwatch/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nightwatch/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nightwatch/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/nightwatch/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/nightwatch/node_modules/yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-releases": { + "version": "1.1.76", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", + "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "dev": true + }, + "node_modules/node-source-walk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", + "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.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/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pac-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^5.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pac-resolver": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz", + "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==", + "dev": true, + "dependencies": { + "degenerator": "^3.0.1", + "ip": "^1.1.5", + "netmask": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "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-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "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/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.3.7", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.7.tgz", + "integrity": "sha512-9SaY7nnyQ63/WittqZYAvkkYPyKxchMKH71UDzeTmWuLSvxTRpeEeABZAzlCi55cuGcoFyoV/amX2BdsafQidQ==", + "dev": true, + "dependencies": { + "nanocolors": "^0.1.5", + "nanoid": "^3.1.25", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-values-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-5.0.0.tgz", + "integrity": "sha512-2viDDjMMrt21W2izbeiJxl3kFuD/+asgB0CBwPEgSyhCmBnDIa/y+pLaoyX+q3I3DHH0oPPL3cgjVTQvlS1Maw==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/precinct": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.1.0.tgz", + "integrity": "sha512-oeZBR9IdER42Ef6Rz11z1oOUqicsI5J1Qffj6tYghKLhxN2UnHy7uE1axxNr0VZRevPK2HWkROk36uXrbJwHFA==", + "dev": true, + "dependencies": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "detective-amd": "^3.0.1", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "module-definition": "^3.3.1", + "node-source-walk": "^4.2.0" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": "^10.13 || ^12 || >=14" + } + }, + "node_modules/precinct/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/precinct/node_modules/detective-postcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-4.0.0.tgz", + "integrity": "sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "is-url": "^1.2.4", + "postcss": "^8.1.7", + "postcss-values-parser": "^2.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/precinct/node_modules/postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^5.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "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/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.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/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha1-Z6mncUjv/q+BpNQoQEpxC6qsigs=", + "dev": true + }, + "node_modules/ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/read-installed/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "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/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", + "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", + "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true, + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-dependency-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", + "integrity": "sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w==", + "dev": true, + "engines": { + "node": ">=6.0.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/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass-lookup": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-3.0.0.tgz", + "integrity": "sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg==", + "dev": true, + "dependencies": { + "commander": "^2.16.0" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/sass-lookup/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "dev": true, + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "node_modules/spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "node_modules/spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "dependencies": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/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.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/stylus-lookup": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-3.0.2.tgz", + "integrity": "sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg==", + "dev": true, + "dependencies": { + "commander": "^2.8.1", + "debug": "^4.1.0" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/stylus-lookup/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "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/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/temp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.4.0.tgz", + "integrity": "sha1-ZxrWPVe+D+nXKUZks/xABjZnimA=", + "dev": true, + "engines": [ + "node >=0.4.0" + ] + }, + "node_modules/terser": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", + "dev": true, + "dependencies": { + "jest-worker": "^27.0.6", + "p-limit": "^3.1.0", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "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": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "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-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vm2": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.3.tgz", + "integrity": "sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q==", + "dev": true, + "bin": { + "vm2": "bin/vm2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.53.0.tgz", + "integrity": "sha512-RZ1Z3z3ni44snoWjfWeHFyzvd9HMVYDYC5VXmlYUT6NWgEOWdCNpad5Fve2CzzHoRED7WtsKe+FCyP5Vk4pWiQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^3.2.0" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz", + "integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.0.4", + "@webpack-cli/info": "^1.3.0", + "@webpack-cli/serve": "^1.5.2", + "colorette": "^1.2.1", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", + "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/acorn-import-assertions": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", + "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "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/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "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/workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, + "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": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "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/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.0.tgz", + "integrity": "sha512-UPeZv4h9Xv510ibpt5rdsUNzgD78nMa1rhxxCgvkKiq06hlKCEHJLiJ6Ub8zDg/wR6hedEI6ovnd2vCvJ4nusA==", + "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": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", + "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", + "dev": true + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", + "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "@js-soft/eslint-config-ts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@js-soft/eslint-config-ts/-/eslint-config-ts-1.3.3.tgz", + "integrity": "sha512-A+6uBaBXP44rmRLG2rtrmAE8r4xLh7npFIXMwzxD32Y8TEJX3Qj2WaaoQA3TjedvANQUtWYr2QDpoNuKWC9aAA==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^4.31.1", + "@typescript-eslint/parser": "^4.31.1", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.7.2", + "eslint-plugin-jest": "^24.4.2", + "eslint-plugin-mocha": "^9.0.0" + } + }, + "@js-soft/license-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@js-soft/license-check/-/license-check-1.0.2.tgz", + "integrity": "sha512-r/JBeQsZ82WIoOjLueFNDdSa/7++6af+NlWuSSmmo9QJqeRjbDAYJnlG5ZXfdm0B4sk1S4gMf90WeTO7KtG83w==", + "dev": true, + "requires": { + "license-checker": "^25.0.1", + "yargs": "^17.2.0" + } + }, + "@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" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/chai": { + "version": "4.2.22", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", + "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", + "dev": true + }, + "@types/eslint": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "@types/node": { + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", + "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.31.2", + "@typescript-eslint/scope-manager": "4.31.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", + "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", + "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", + "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2" + } + }, + "@typescript-eslint/types": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", + "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", + "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", + "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.31.2", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz", + "integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz", + "integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz", + "integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "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": {} + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "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" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "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" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "ast-module-types": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", + "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "dev": true + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "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 + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "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" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", + "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001259", + "electron-to-chromium": "^1.3.846", + "escalade": "^3.1.1", + "nanocolors": "^0.1.5", + "node-releases": "^1.1.76" + } + }, + "bt-runner": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/bt-runner/-/bt-runner-1.0.17.tgz", + "integrity": "sha512-DhedhWeeNC4wtFXp/9eUPq8/rdUcTG+GNVWW5QxubOgJuOtoQ+iWGw7hStjOzqayGNVMsRR6NrJPmRNoILU5ng==", + "dev": true, + "requires": { + "chai": "^4.3.4", + "express": "^4.17.1", + "express-http-proxy": "^1.6.2", + "mocha": "^9.1.1", + "nightwatch": "^1.7.11", + "rimraf": "^3.0.2", + "yargs": "^17.1.1" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001260", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001260.tgz", + "integrity": "sha512-Fhjc/k8725ItmrvW5QomzxLeojewxvqiYCKeFcfFEhut28IVLdpHU19dneOmltZQIE5HNbawj1HYD+1f2bM1Dg==", + "dev": true, + "requires": { + "nanocolors": "^0.1.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chai-nightwatch": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/chai-nightwatch/-/chai-nightwatch-0.4.1.tgz", + "integrity": "sha512-s2put5cFhG8Hw+6Po3R8QZ0ctsDmcaIh7+l9Fu3RcLCfosfQffT3mcFSq2jmXEQk0pmwo/PuXvYMO87MRlyqxg==", + "dev": true, + "requires": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + }, + "dependencies": { + "assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "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" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "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" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.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 + }, + "colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "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" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "decomment": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.4.tgz", + "integrity": "sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw==", + "dev": true, + "requires": { + "esprima": "4.0.1" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "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 + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "degenerator": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz", + "integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==", + "dev": true, + "requires": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.3" + }, + "dependencies": { + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "dependency-tree": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-8.1.1.tgz", + "integrity": "sha512-bl5U16VQpaYxD0xvcnCH/dTctCiWnsVWymh9dNjbm4T00Hm21flu1VLnNueKCj7+3uusbcJhKKKtiWrpU0I+Nw==", + "dev": true, + "requires": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "filing-cabinet": "^3.0.0", + "precinct": "^8.0.0", + "typescript": "^3.9.7" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true + } + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detective-amd": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.0.tgz", + "integrity": "sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw==", + "dev": true, + "requires": { + "ast-module-types": "^2.7.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^3.0.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-cjs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.1.tgz", + "integrity": "sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg==", + "dev": true, + "requires": { + "ast-module-types": "^2.4.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-es6": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.0.tgz", + "integrity": "sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ==", + "dev": true, + "requires": { + "node-source-walk": "^4.0.0" + } + }, + "detective-less": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/detective-less/-/detective-less-1.0.2.tgz", + "integrity": "sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-postcss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-5.0.0.tgz", + "integrity": "sha512-IBmim4GTEmZJDBOAoNFBskzNryTmYpBq+CQGghKnSGkoGWascE8iEo98yA+ZM4N5slwGjCr/NxCm+Kzg+q3tZg==", + "dev": true, + "requires": { + "debug": "^4.3.1", + "is-url": "^1.2.4", + "postcss": "^8.2.13", + "postcss-values-parser": "^5.0.0" + } + }, + "detective-sass": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.1.tgz", + "integrity": "sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-scss": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.1.tgz", + "integrity": "sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-stylus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.0.tgz", + "integrity": "sha1-UK7n24uruZA4HwEMY/q7pbWOVM0=", + "dev": true + }, + "detective-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.0.tgz", + "integrity": "sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "^4.8.2", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.7" + }, + "dependencies": { + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true + } + } + }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "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" + } + }, + "dotenv": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", + "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dev": true, + "requires": { + "jake": "^10.6.1" + } + }, + "electron-to-chromium": { + "version": "1.3.849", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.849.tgz", + "integrity": "sha512-RweyW60HPOqIcxoKTGr38Yvtf2aliSUqX8dB3e9geJ0Bno0YLjcOX5F7/DPVloBkJWaPZ7xOM1A0Yme2T1A34w==", + "dev": true + }, + "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 + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-abstract": { + "version": "1.18.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", + "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "dependencies": { + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, + "es-module-lexer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==", + "dev": true + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "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-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "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 + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + } + } + }, + "eslint-plugin-chai-expect": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", + "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", + "dev": true, + "requires": {} + }, + "eslint-plugin-chai-friendly": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", + "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "dev": true, + "requires": {} + }, + "eslint-plugin-jest": { + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, + "eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "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" + } + }, + "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 + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "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 + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "express-http-proxy": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.6.2.tgz", + "integrity": "sha512-soP7UXySFdLbeeMYL1foBkEoZj6HELq9BDAOCr1sLRpqjPaFruN5o6+bZeC+7U4USWIl4JMKEiIvTeKJ2WQdlQ==", + "dev": true, + "requires": { + "debug": "^3.0.1", + "es6-promise": "^4.1.1", + "raw-body": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "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-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "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": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "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" + } + }, + "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" + } + }, + "file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "dev": true + }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "filing-cabinet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.0.0.tgz", + "integrity": "sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw==", + "dev": true, + "requires": { + "app-module-path": "^2.2.0", + "commander": "^2.20.3", + "debug": "^4.3.1", + "decomment": "^0.9.3", + "enhanced-resolve": "^5.3.2", + "is-relative-path": "^1.0.2", + "module-definition": "^3.3.1", + "module-lookup-amd": "^7.0.0", + "resolve": "^1.19.0", + "resolve-dependency-path": "^2.0.0", + "sass-lookup": "^3.0.0", + "stylus-lookup": "^3.0.1", + "typescript": "^3.9.7" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "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": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "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.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-amd-module-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz", + "integrity": "sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw==", + "dev": true, + "requires": { + "ast-module-types": "^2.3.2", + "node-source-walk": "^4.0.0" + } + }, + "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 + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "graphviz": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz", + "integrity": "sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==", + "dev": true, + "requires": { + "temp": "~0.4.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "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 + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "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" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^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-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "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 + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-relative-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", + "integrity": "sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-worker": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz", + "integrity": "sha512-laB0ZVIBz+voh/QQy9dmUuuDsadixeerrKqyVpgPz+CCWiOYjOBabUXHIXZhsdvkWbLqSHbgkAHWl5cg24Q6RA==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "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" + } + }, + "license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "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": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=", + "dev": true + }, + "lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=", + "dev": true + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._baseclone": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", + "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=", + "dev": true, + "requires": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._baseassign": "^3.0.0", + "lodash._basefor": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=", + "dev": true + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.clone": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz", + "integrity": "sha1-hGiMc9MrWpDKJWFpY/GJJSqZcEM=", + "dev": true, + "requires": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.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 + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "madge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/madge/-/madge-5.0.1.tgz", + "integrity": "sha512-krmSWL9Hkgub74bOjnjWRoFPAJvPwSG6Dbta06qhWOq6X/n/FPzO3ESZvbFYVIvG2g4UHXvCJN1b+RZLaSs9nA==", + "dev": true, + "requires": { + "chalk": "^4.1.1", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.1", + "dependency-tree": "^8.1.1", + "detective-amd": "^3.1.0", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^5.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "graphviz": "0.0.9", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "precinct": "^8.1.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.7", + "typescript": "^3.9.5", + "walkdir": "^0.4.1" + }, + "dependencies": { + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "requires": { + "mime-db": "1.49.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", + "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", + "dev": true + }, + "mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.23", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "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 + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "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 + } + } + }, + "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" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "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" + } + } + } + }, + "module-definition": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.3.1.tgz", + "integrity": "sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A==", + "dev": true, + "requires": { + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.0.0" + } + }, + "module-lookup-amd": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz", + "integrity": "sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ==", + "dev": true, + "requires": { + "commander": "^2.8.1", + "debug": "^4.1.0", + "glob": "^7.1.6", + "requirejs": "^2.3.5", + "requirejs-config-file": "^4.0.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "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 + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanocolors": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz", + "integrity": "sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==", + "dev": true + }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true + }, + "nightwatch": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.7.11.tgz", + "integrity": "sha512-yV795EBXZ/myeoCvBtjC/QwvIprxF7SKh0XCeFnpoOtWXDb0yv+ATLRipKGfp+avyGtagqq38ucA4Uh6WPcnhQ==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "chai-nightwatch": "^0.4.0", + "ci-info": "^2.0.0", + "didyoumean": "^1.2.1", + "dotenv": "7.0.0", + "ejs": "^3.1.6", + "envinfo": "^7.5.1", + "lodash.clone": "3.0.3", + "lodash.defaultsdeep": "^4.6.1", + "lodash.merge": "^4.6.2", + "minimatch": "3.0.4", + "minimist": "^1.2.5", + "mkpath": "1.0.0", + "mocha": "6.2.3", + "ora": "^4.0.3", + "proxy-agent": "^5.0.0", + "request": "^2.88.2", + "request-promise": "^4.2.5", + "semver": "^6.3.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "ora": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", + "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "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" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.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 + }, + "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 + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "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" + } + } + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + } + } + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-releases": { + "version": "1.1.76", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", + "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "dev": true + }, + "node-source-walk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", + "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "dev": true, + "requires": { + "@babel/parser": "^7.0.0" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "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" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "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" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pac-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^5.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + } + }, + "pac-resolver": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz", + "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==", + "dev": true, + "requires": { + "degenerator": "^3.0.1", + "ip": "^1.1.5", + "netmask": "^2.0.1" + } + }, + "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-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "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 + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "postcss": { + "version": "8.3.7", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.7.tgz", + "integrity": "sha512-9SaY7nnyQ63/WittqZYAvkkYPyKxchMKH71UDzeTmWuLSvxTRpeEeABZAzlCi55cuGcoFyoV/amX2BdsafQidQ==", + "dev": true, + "requires": { + "nanocolors": "^0.1.5", + "nanoid": "^3.1.25", + "source-map-js": "^0.6.2" + }, + "dependencies": { + "nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true + } + } + }, + "postcss-values-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-5.0.0.tgz", + "integrity": "sha512-2viDDjMMrt21W2izbeiJxl3kFuD/+asgB0CBwPEgSyhCmBnDIa/y+pLaoyX+q3I3DHH0oPPL3cgjVTQvlS1Maw==", + "dev": true, + "requires": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + } + }, + "precinct": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.1.0.tgz", + "integrity": "sha512-oeZBR9IdER42Ef6Rz11z1oOUqicsI5J1Qffj6tYghKLhxN2UnHy7uE1axxNr0VZRevPK2HWkROk36uXrbJwHFA==", + "dev": true, + "requires": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "detective-amd": "^3.0.1", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "module-definition": "^3.3.1", + "node-source-walk": "^4.2.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "detective-postcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-4.0.0.tgz", + "integrity": "sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "is-url": "^1.2.4", + "postcss": "^8.1.7", + "postcss-values-parser": "^2.0.1" + } + }, + "postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true + }, + "pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "requires": { + "parse-ms": "^2.1.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", + "dev": true, + "requires": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^5.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "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 + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "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 + }, + "quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha1-Z6mncUjv/q+BpNQoQEpxC6qsigs=", + "dev": true + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "request-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", + "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, + "requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "requires": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-dependency-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", + "integrity": "sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w==", + "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 + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "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" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass-lookup": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-3.0.0.tgz", + "integrity": "sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg==", + "dev": true, + "requires": { + "commander": "^2.16.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "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 + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true + }, + "socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true + }, + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "requires": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "requires": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "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-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "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 + }, + "stylus-lookup": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-3.0.2.tgz", + "integrity": "sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg==", + "dev": true, + "requires": { + "commander": "^2.8.1", + "debug": "^4.1.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "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" + } + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "temp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.4.0.tgz", + "integrity": "sha1-ZxrWPVe+D+nXKUZks/xABjZnimA=", + "dev": true + }, + "terser": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", + "dev": true, + "requires": { + "jest-worker": "^27.0.6", + "p-limit": "^3.1.0", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true + }, + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "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-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "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 + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "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" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm2": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.3.tgz", + "integrity": "sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q==", + "dev": true + }, + "walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webpack": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.53.0.tgz", + "integrity": "sha512-RZ1Z3z3ni44snoWjfWeHFyzvd9HMVYDYC5VXmlYUT6NWgEOWdCNpad5Fve2CzzHoRED7WtsKe+FCyP5Vk4pWiQ==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.7.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^3.2.0" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", + "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", + "dev": true, + "requires": {} + } + } + }, + "webpack-cli": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz", + "integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.0.4", + "@webpack-cli/info": "^1.3.0", + "@webpack-cli/serve": "^1.5.2", + "colorette": "^1.2.1", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^5.7.3" + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", + "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", + "dev": true + }, + "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" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "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 + }, + "workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "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": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "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 + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.0.tgz", + "integrity": "sha512-UPeZv4h9Xv510ibpt5rdsUNzgD78nMa1rhxxCgvkKiq06hlKCEHJLiJ6Ub8zDg/wR6hedEI6ovnd2vCvJ4nusA==", + "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.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "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 + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..786d1b0 --- /dev/null +++ b/package.json @@ -0,0 +1,68 @@ +{ + "name": "@js-soft/ts-serval", + "version": "1.0.0", + "description": "TypeScript Runtime Serialization and Validation", + "homepage": "https://github.com/js-soft/ts-serval#readme", + "repository": "github:js-soft/ts-serval", + "license": "MIT", + "author": "j&s-soft GmbH", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "lib-web/tsserval.js", + "lib-web/tsserval.min.js", + "lib-web/tsserval.js.map", + "lib-web/tsserval.min.js.map", + "ui5.yaml" + ], + "scripts": { + "lint": "npm run lint:prettier && npm run lint:eslint && npm run lint:tsc", + "lint:prettier": "prettier --check .", + "lint:eslint": "eslint --ext .ts ./src ./test", + "lint:tsc": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit", + "bt": "npm run test:node && npm run build:node && npm run build:test && npm run bundle && npm run test:web", + "build": "npm run build:node && npm run bundle", + "build:node": "tsc -p tsconfig.json && madge --circular dist", + "build:ci": "npm run build:node && .ci/writeBuildInformation.sh && npm run build:test && npm run bundle", + "build:test": "tsc -p tsconfig.test.json", + "bundle": "npm run bundle:lib && npm run bundle:min && npm run bundle:test", + "bundle:lib": "webpack --stats-all --config webpack.config.js", + "bundle:min": "webpack --stats-all --config webpack.min.config.js", + "bundle:test": "webpack --stats-all --config webpack.test.config.js", + "cdep": "tsc && madge --circular dist", + "test:local": "npm run test", + "test:local:node": "npm run test:node", + "test:ci": "npm run test", + "test": "npm run test:node && npm run test:web", + "test:node": "mocha -r ts-node/register -r tsconfig-paths/register ./test/index.ts --project ./test/tsconfig.json --exit", + "test:web": "browsertest-runner", + "test:web:debug": "browsertest-runner-debug" + }, + "dependencies": { + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@js-soft/eslint-config-ts": "1.3.3", + "@js-soft/license-check": "1.0.2", + "@types/chai": "^4.2.22", + "@types/mocha": "^9.0.0", + "@types/node": "^16.9.6", + "bt-runner": "^1.0.17", + "buffer": "^6.0.3", + "chai": "^4.3.4", + "eslint": "7.32.0", + "madge": "^5.0.1", + "mocha": "^9.1.1", + "prettier": "^2.4.1", + "terser-webpack-plugin": "5.2.4", + "ts-node": "^10.2.1", + "tsconfig-paths": "^3.11.0", + "typescript": "^4.4.3", + "webpack": "^5.53.0", + "webpack-cli": "^4.8.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/src/Serializable.ts b/src/Serializable.ts new file mode 100644 index 0000000..3318b3f --- /dev/null +++ b/src/Serializable.ts @@ -0,0 +1,114 @@ +import { ServalError } from "./errors" +import { Constructor, ISerializable } from "./interfaces" +import { Parser } from "./parsing/Parser" +import { ParsingError } from "./parsing/ParsingError" +import { IReflectProperty } from "./reflection/ReflectProperty" +import { SerializableBase } from "./SerializableBase" + +export class Serializable extends SerializableBase implements ISerializable { + public static fromUnknown(value: any): Serializable { + const obj: any = value + if (obj["@type"]) { + const result = SerializableBase.getModule(obj["@type"]) + if (!result) { + throw new ServalError( + `Type '${obj["@type"]}' was not found within reflection classes. You might have to install a module first.` + ) + } + if (typeof result.fromJSON === "function") { + return result.fromJSON(value) + } + return result.from(value, result) + } + return Serializable.from(value) + } + + public static deserializeUnknown(value: string): Serializable { + let obj + try { + obj = JSON.parse(value) + } catch (e) { + throw new ServalError(`DeserializationError ${e}`) + } + return this.fromUnknown(obj) + } + + /** + * Deserializes the given string to the current class. + * + * @param value The JSON string which should be parsed + * @returns An object of the given type T + */ + public static deserializeT(value: string, type: new () => T): T { + let obj + try { + obj = JSON.parse(value) + } catch (e) { + throw new ParsingError( + type.name, + "deserialize()", + "The given String value is not in JSON format and could not be deserialized.", + e + ) + } + return this.fromT(obj, type) + } + + /** + * Parsed the given object to the current class. + * + * @param value The object which should be parsed + * @returns An object of the given type T + * + * @throws DeserializationError when the deserialization failed (structure is not correct) + * @throws ValidationError when the validation of field failed (structure is correct but content is not) + */ + public static fromT(value: any, type: new () => T): T { + if (typeof value === "undefined" || value === null || typeof value !== "object") { + throw new ParsingError(type.name, "from()", `Parameter must be an object - is '${value}'`) + } + + const realObj: T = new (>type)() + const propertyMap = SerializableBase.getDescriptor(type.name) + if (propertyMap) { + propertyMap.forEach((info: IReflectProperty, key: string) => { + if (key === "@type" || key === "@context" || key === "serializeProperty" || key === "serializeAs") { + return + } + + let jsonKey = key + if (typeof value[jsonKey] === "undefined" && info.alias) { + jsonKey = info.alias + } + + const propertyValue = Parser.parseProperty( + value[jsonKey], + info, + (realObj as Object).constructor.name, + Serializable + ) + if (typeof propertyValue !== "undefined") { + realObj[info.key] = propertyValue + } + }) + } + return realObj + } + + public static deserialize(value: string, type?: new () => Serializable): Serializable { + if (type) { + return this.deserializeT(value, type) + } + return this.deserializeUnknown(value) + } + + public static from(value: ISerializable, type?: new () => Serializable): Serializable { + if (!type || type === Serializable) { + if (!value["@type"]) { + value["@type"] = "JSONWrapper" + } + return this.fromUnknown(value) + } + return this.fromT(value, type) + } +} diff --git a/src/SerializableAsync.ts b/src/SerializableAsync.ts new file mode 100644 index 0000000..b3f04d1 --- /dev/null +++ b/src/SerializableAsync.ts @@ -0,0 +1,146 @@ +import { ServalError } from "./errors" +import { Constructor, ISerializable, ISerializableAsync } from "./interfaces" +import { Parser } from "./parsing/Parser" +import { ParsingError } from "./parsing/ParsingError" +import { IReflectProperty } from "./reflection/ReflectProperty" +import { Serializable } from "./Serializable" +import { SerializableBase } from "./SerializableBase" +import { Validator } from "./validation/Validator" + +export class SerializableAsync extends SerializableBase implements ISerializable { + public static async fromUnknown(value: any): Promise { + const obj: any = value + if (obj["@type"]) { + const result = SerializableBase.getModule(obj["@type"]) + if (!result) { + throw new ServalError( + `Type '${obj["@type"]}' was not found within reflection classes. You might have to install a module first.` + ) + } + if (typeof result.fromJSON === "function") { + return result.fromJSON(value) + } + return result.from(value, result) + } + return await this.from(value) + } + + public static async deserializeUnknown(value: string): Promise { + let obj + try { + obj = JSON.parse(value) + } catch (e) { + throw new ServalError(`ParsingError ${e}`) + } + return await this.fromUnknown(obj) + } + + public static async deserialize(value: string, type?: new () => SerializableAsync): Promise { + if (type) { + return await this.deserializeT(value, type) + } + return await this.deserializeUnknown(value) + } + + /** + * Deserializes the given string to the current class. + * + * @param value The JSON string which should be parsed + * @returns An object of the given type T + */ + public static async deserializeT(value: string, type: new () => T): Promise { + let obj + try { + obj = JSON.parse(value) + } catch (e) { + throw new ParsingError( + type.name, + "deserialize()", + "The given String value is not in JSON format and could not be deserialized.", + e + ) + } + return await this.fromT(obj, type) + } + + public static async from( + value: ISerializableAsync, + type?: new () => SerializableAsync + ): Promise { + if (!type || type === SerializableAsync || type === Serializable) { + if (!value["@type"]) { + value["@type"] = "JSONWrapperAsync" + } + return await this.fromUnknown(value) + } + return await this.fromT(value, type) + } + + /** + * Parsed the given object to the current class. + * + * @param value The object which should be parsed + * @returns An object of the given type T + * + * @throws ParsingError when the deserialization failed (structure is not correct) + * @throws ValidationError when the validation of field failed (structure is correct but content is not) + */ + public static async fromT(value: any, type: new () => T): Promise { + if (typeof value === "undefined" || value === null || typeof value !== "object") { + throw new ParsingError(type.name, "from()", `Parameter must be an object - is '${value}'`) + } + + const realObj: T = new (>type)() + const propertyMap = SerializableBase.getDescriptor(type.name) + if (propertyMap) { + for (const [key, info] of propertyMap.entries()) { + if (key === "@type" || key === "@context" || key === "serializeProperty" || key === "serializeAs") { + continue + } + + let jsonKey = key + if (typeof value[jsonKey] === "undefined" && info.alias) { + jsonKey = info.alias + } + + const propertyValue = await Parser.parsePropertyAsync( + value[jsonKey], + info, + (realObj as Object).constructor.name, + SerializableAsync + ) + if (typeof propertyValue !== "undefined") { + realObj[info.key] = propertyValue + } + } + } + return realObj + } + + public validateProperty(key: string, descriptor?: IReflectProperty): string | undefined { + if (!descriptor) { + const propertyMap = this.getDescriptor() + if (!propertyMap) { + return `No descriptor available for key ${key} (propertyMap is missing)` + } + descriptor = propertyMap.get(key) + } + if (!descriptor) { + return `No descriptor available for key ${key}` + } + + return Validator.checkProperty(this[key], descriptor) + } + + public static checkProperty(value: any, key: string, className: string): string | undefined { + const propertyMap = Serializable.getDescriptor(className) + if (!propertyMap) { + return `No descriptor available for key ${key} (propertyMap is missing)` + } + const descriptor = propertyMap.get(key) + if (!descriptor) { + return `No descriptor available for key ${key}` + } + return Validator.checkProperty(value, descriptor) + } +} diff --git a/src/SerializableBase.ts b/src/SerializableBase.ts new file mode 100644 index 0000000..8e475ed --- /dev/null +++ b/src/SerializableBase.ts @@ -0,0 +1,274 @@ +import { SerializationError } from "./errors" +import { IReflectProperty } from "./reflection/ReflectProperty" +import { Validator } from "./validation/Validator" + +export class SerializableBase { + public static __classes: Map> // eslint-disable-line @typescript-eslint/naming-convention + public static __modules: any[] = [SerializableBase] // eslint-disable-line @typescript-eslint/naming-convention + private readonly __propertyMap: Map | undefined // eslint-disable-line @typescript-eslint/naming-convention + + public static addModule(syncModule: any): void { + SerializableBase.__modules.push(syncModule) + } + + public static getModule(type: string): any { + for (const module of SerializableBase.__modules) { + const implementation = Reflect.getMetadata(type, module, "types") + if (implementation) return implementation + } + return null + } + + public constructor() { + this.__propertyMap = SerializableBase.getDescriptor(this.constructor.name) + if (this.__propertyMap) { + SerializableBase.copyDescriptorsFromPrototypeChain(this.__propertyMap, (this as any).constructor.prototype) + } + } + + private static copyDescriptorsFromPrototypeChain( + storeInMap: Map, + currentPrototype: any + ): void { + const name: string = currentPrototype.__proto__.constructor.name + if ( + name === "Function" || + name === "Object" || + name === "Serializable" || + name === "SerializableAsync" || + name === "SerializableBase" + ) { + return + } + const currentDescriptors = SerializableBase.getDescriptor(name) + if (currentDescriptors) { + currentDescriptors.forEach((value, key) => { + if (key === "@type" || key === "@schema") return + storeInMap.set(key, value) + }) + } + + SerializableBase.copyDescriptorsFromPrototypeChain(storeInMap, currentPrototype.__proto__) + } + + public static getDescriptor(target: string): Map | undefined { + const map = SerializableBase.__classes.get(target) + return map + } + + public getDescriptor(): Map | undefined { + return this.__propertyMap + } + + /** + * Validates all defined properties on this object + * + * @returns Either an error string or undefined (no errors) + */ + public validate(): string | undefined { + let err + const propertyMap = this.getDescriptor() + if (propertyMap) { + for (const [key, info] of propertyMap) { + if (key === "@type" || key === "@context" || key === "serializeProperty" || key === "serializeAs") { + continue + } + + err = this.validateProperty(key, info) + if (err) { + return `Validating ${key}:${info.type} :: ${err}` + } + } + } + return undefined + } + + public validateProperty(key: string, descriptor?: IReflectProperty): string | undefined { + if (!descriptor) { + const propertyMap = this.getDescriptor() + if (!propertyMap) { + return `No descriptor available for key ${key} (propertyMap is missing)` + } + descriptor = propertyMap.get(key) + } + if (!descriptor) { + return `No descriptor available for key ${key}` + } + + return Validator.checkProperty(this[key], descriptor) + } + + public static checkProperty(value: any, key: string, className: string): string | undefined { + const propertyMap = this.getDescriptor(className) + if (!propertyMap) { + return `No descriptor available for key ${key} (propertyMap is missing)` + } + const descriptor = propertyMap.get(key) + if (!descriptor) { + return `No descriptor available for key ${key}` + } + return Validator.checkProperty(value, descriptor) + } + + /** + * Serializes the object by calling JSON.stringify + * + * @returns The serialized JSON string "{...}" + */ + public serialize(verbose = true): string { + return JSON.stringify(this.toJSON(verbose, false)) + } + + /** + * Returns an object representation of this object. Careful, this is not a string - if + * you require a string call [[serialize()]] instead. + * + * @returns An object representation of this object {...} + */ + public toJSON(verbose = true, serializeAsString = false): Object { + const obj: any = {} + const propertyMap = this.getDescriptor() + let serializeAs: "number" | "boolean" | "string" | "array" | "object" = "object" + let serializeProperty: string | undefined = undefined + if (propertyMap) { + propertyMap.forEach((info: IReflectProperty, key: string) => { + if (key === "serializeAs") { + serializeAs = info.value + } else if (key === "serializeProperty") { + serializeProperty = info.value + } else if (key === "@type") { + if (verbose) { + obj[key] = info.value + } + } else if (key === "@context") { + if (verbose) { + obj[key] = info.value + } + } else if (key === "@version") { + obj[key] = info.value + } else { + const jsonKey = info.alias ? info.alias : key + const value = this.serializeProperty(this[key], info, false, serializeAsString) + if (typeof value !== "undefined") { + obj[jsonKey] = value + } + } + }) + } + if (typeof serializeAs !== "undefined" && typeof serializeProperty !== "undefined") { + if (!propertyMap?.has(serializeProperty)) { + throw new SerializationError( + this.constructor.name, + serializeProperty, + "Property is not available in object but is the only property which should be serialized." + ) + } + return this.serializeProperty( + this[serializeProperty], + propertyMap.get(serializeProperty)!, + false, + serializeAsString + ) + } + const newObj: any = {} + const keys: string[] = [] + for (const prop in obj) { + if (obj.hasOwnProperty(prop)) { + keys.push(prop) + } + } + keys.sort() + for (let i = 0, l = keys.length; i < l; i++) { + newObj[keys[i]] = obj[keys[i]] + } + return newObj + } + + private serializeProperty( + value: any, + descriptor: IReflectProperty, + verbose = false, + serializeAsString = false + ): any { + // Do not render out the property if the value is undefined and the property is optional + if (descriptor.optional && typeof value === "undefined") { + return undefined + } + + // Do render null if the property is not set + if (Validator.checkDefined(value, descriptor)) { + return null + } + + if (typeof descriptor.customSerializer === "function" && serializeAsString) { + const ret = descriptor.customSerializer(value, descriptor, verbose) + return ret + } + + if (typeof descriptor.customGenerator === "function") { + const ret = descriptor.customGenerator(value, descriptor, verbose) + return ret + } + + switch (descriptor.type) { + case "Number": + case "Boolean": + case "String": + return value + + case "Array": + if (!descriptor.itemDescriptor) { + throw new SerializationError( + this.constructor.name, + descriptor.key, + "No itemDescriptor for Array set." + ) + } + const ar: any[] = [] + + if (!value) { + return ar + } + + for (const element of value) { + ar.push(this.serializeProperty(element, descriptor.itemDescriptor, verbose, serializeAsString)) + } + + return ar + default: + // We always require the type information if it could be anything + if (descriptor.any) { + verbose = true + } + + // We require the type information if we have subclasses of the given types + const valueProt = Object.getPrototypeOf(value) + if ( + (typeof descriptor.allowSubclasses === "undefined" || descriptor.allowSubclasses) && + typeof value === "object" && + valueProt !== descriptor.typeInfo.prototype + ) { + verbose = true + } + if (value instanceof SerializableBase) { + if (descriptor.enforceString || serializeAsString) { + return value.serialize(verbose) + } + return value.toJSON(verbose) + } else if (value instanceof Promise) { + throw new SerializationError( + this.constructor.name, + descriptor.key, + "Object is not yet resolved. You have to wait for Promises to proceed with serialization." + ) + } else if (typeof value.toJSON === "function") { + if (descriptor.enforceString || serializeAsString) { + return JSON.stringify(value.toJSON()) + } + return value.toJSON() + } else { + return value + } + } + } +} diff --git a/src/ServalBuildInformation.ts b/src/ServalBuildInformation.ts new file mode 100644 index 0000000..f263f54 --- /dev/null +++ b/src/ServalBuildInformation.ts @@ -0,0 +1,18 @@ +export class ServalBuildInformation { + public readonly version: string = "{{version}}" + public readonly build: string = "{{build}}" + public readonly date: string = "{{date}}" + public readonly commit: string = "{{commit}}" + public readonly dependencies: object + + private constructor() { + try { + // eslint-disable-next-line @typescript-eslint/quotes + this.dependencies = JSON.parse(`{{dependencies}}`) + } catch (e) { + this.dependencies = {} + } + } + + public static readonly info: ServalBuildInformation = new ServalBuildInformation() +} diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..9910c5e --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,42 @@ +export class ServalError extends Error {} + +export class SerializationError extends ServalError { + public type: string + public property: string + public reason: string + public cause: Error | undefined + + public constructor(type: string, property: string, reason: string, cause?: Error) { + super(`${type}.${property} :: ${reason}`) + + Object.setPrototypeOf(this, new.target.prototype) + this.name = SerializationError.name + this.type = type + this.property = property + this.reason = reason + this.cause = cause + } + + public toString(): string { + if (this.cause) { + return `${this.type}.${this.property} :: ${this.reason}\n\n${this.cause.stack}` + } + return `${this.type}.${this.property} :: ${this.reason}` + } +} + +export class DecoratorError extends ServalError { + public decorator: string + + public constructor(decorator: string, message?: string) { + super(message) + + Object.setPrototypeOf(this, new.target.prototype) + this.name = DecoratorError.name + this.decorator = decorator + } + + public toString(): string { + return `${this.decorator} :: ${this.message}` + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..91e04fe --- /dev/null +++ b/src/index.ts @@ -0,0 +1,18 @@ +export * from "./errors" +export * from "./interfaces" +export * from "./parsing/ParsingError" +export * from "./reflection/globals" +export * from "./reflection/ReflectProperty" +export * from "./Serializable" +export * from "./SerializableAsync" +export * from "./SerializableBase" +export * from "./serialization/Serialize" +export * from "./serialization/SerializeParameter" +export * from "./ServalBuildInformation" +export * from "./validation/Validate" +export * from "./validation/ValidateGlobals" +export * from "./validation/ValidateInterfaces" +export * from "./validation/ValidationError" +export * from "./validation/Validator" +export * from "./wrapper/JSONWrapper" +export * from "./wrapper/JSONWrapperAsync" diff --git a/src/interfaces.ts b/src/interfaces.ts new file mode 100644 index 0000000..4d964bb --- /dev/null +++ b/src/interfaces.ts @@ -0,0 +1,13 @@ +export interface Constructor { + new (...args: any[]): T +} + +export interface ISerializable {} + +export interface ISerializableAsync {} + +export interface ISerialized { + "@context"?: string + "@type"?: string + "@version"?: string +} diff --git a/src/parsing/Parser.ts b/src/parsing/Parser.ts new file mode 100644 index 0000000..cbb7cd2 --- /dev/null +++ b/src/parsing/Parser.ts @@ -0,0 +1,440 @@ +import { ServalError } from "../errors" +import { IReflectProperty } from "../reflection/ReflectProperty" +import { PrimitiveType } from "../validation/ValidateInterfaces" +import { Validator } from "../validation/Validator" +import { ParsingError } from "./ParsingError" + +export abstract class Parser { + public static parseProperty(value: any, descriptor: IReflectProperty, className: string, caller: any): any { + // *****CAUTION: Check Validator.checkProperty if you make changes here!***** + let err: string | undefined + if (!descriptor.optional) { + err = Validator.checkDefined(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + } + + if (descriptor.optional && typeof value === "undefined") { + return undefined + } + + err = Validator.checkTypes(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + + if (descriptor.any) return value + + if (!descriptor.type) descriptor.type = "object" + + switch (descriptor.primitiveType) { + case "array": + return Parser.parseArray(value, descriptor, className, caller) + + case "boolean": + return Parser.parseBoolean(value, descriptor, className) + + case "number": + return Parser.parseNumber(value, descriptor, className) + + case "string": + return Parser.parseString(value, descriptor, className) + default: + // Ignore everything else + break + } + + // Parse possible union types + if (descriptor.allowedTypes) { + if (typeof value === "boolean" && descriptor.allowedTypes.includes(PrimitiveType.Boolean)) { + return Parser.parseBoolean(value, descriptor, className) + } else if (typeof value === "number" && descriptor.allowedTypes.includes(PrimitiveType.Number)) { + return Parser.parseNumber(value, descriptor, className) + } else if ( + typeof value === "string" && + !descriptor.deserializeStrings && + descriptor.allowedTypes.includes(PrimitiveType.String) + ) { + return Parser.parseString(value, descriptor, className) + } else if (Array.isArray(value) && descriptor.allowedTypes.includes(PrimitiveType.Array)) { + return Parser.parseArray(value, descriptor, className, caller) + } + } + + return Parser.parseObject(value, descriptor, className, caller) + } + + public static async parsePropertyAsync( + value: any, + descriptor: IReflectProperty, + className = "Unknown", + caller: any + ): Promise { + if (!descriptor.optional) { + const err = Validator.checkDefined(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + } + + if (descriptor.optional && typeof value === "undefined") { + return undefined + } + + if (descriptor.any) return value + + if (!descriptor.type) descriptor.type = "object" + + switch (descriptor.primitiveType) { + case "array": + return await Parser.parseArrayAsync(value, descriptor, className, caller) + + case "boolean": + return await Promise.resolve(Parser.parseBoolean(value, descriptor, className)) + + case "number": + return await Promise.resolve(Parser.parseNumber(value, descriptor, className)) + + case "string": + return await Promise.resolve(Parser.parseString(value, descriptor, className)) + default: + // Ignore everything else + break + } + + // Parse possible union types + if (descriptor.allowedTypes) { + if (typeof value === "boolean" && descriptor.allowedTypes.includes(PrimitiveType.Boolean)) { + return await Promise.resolve(Parser.parseBoolean(value, descriptor, className)) + } else if (typeof value === "number" && descriptor.allowedTypes.includes(PrimitiveType.Number)) { + return await Promise.resolve(Parser.parseNumber(value, descriptor, className)) + } else if ( + typeof value === "string" && + !descriptor.deserializeStrings && + descriptor.allowedTypes.includes(PrimitiveType.String) + ) { + return await Promise.resolve(Parser.parseString(value, descriptor, className)) + } else if (Array.isArray(value) && descriptor.allowedTypes.includes(PrimitiveType.Array)) { + return await Parser.parseArrayAsync(value, descriptor, className, caller) + } + } + + return await Parser.parseObjectAsync(value, descriptor, className, caller) + } + + public static parseStringObject(value: any, descriptor: IReflectProperty, className: string, caller: any): any { + const classInfo: any = descriptor.typeInfo + const thisObj: any = classInfo + let fct: Function | undefined + const args: any[] = [value] + + if ((descriptor.parseUnknown || descriptor.type === "Serializable") && value && value["@type"]) { + return caller.deserializeUnknown(value) + } + + if (descriptor.customDeserializer) { + fct = descriptor.customDeserializer + args.push(descriptor) + args.push(classInfo) + } + + if (!fct) { + fct = classInfo.deserialize + args.push(classInfo) + } + + if (!fct && descriptor.any) { + return value + } + + if (!fct) { + try { + return JSON.parse(value) + } catch (e) { + throw new ParsingError( + descriptor.type, + descriptor.key, + "Deserialization failed as the given string is not a JSON representation.", + e + ) + } + } + + return fct.apply(thisObj, args) + } + + public static async parseStringObjectAsync( + value: any, + descriptor: IReflectProperty, + _className: string, + caller: any + ): Promise { + const classInfo: any = descriptor.typeInfo + const thisObj: any = classInfo + let fct: Function | undefined + const args: any[] = [value] + + if ( + (descriptor.parseUnknown || + descriptor.type === "Serializable" || + descriptor.type === "SerializableAsync") && + value && + value["@type"] + ) { + // eslint-disable-next-line @typescript-eslint/return-await + return await caller.deserializeUnknown(value) + } + + if (descriptor.customDeserializer) { + fct = descriptor.customDeserializer + args.push(descriptor) + args.push(classInfo) + } + + if (!fct) { + fct = classInfo.deserialize + args.push(classInfo) + } + + if (!fct && descriptor.any) { + return await Promise.resolve(value) + } + + if (!fct) { + try { + const obj = JSON.parse(value) + return obj + } catch (e) { + throw new ParsingError( + descriptor.type, + descriptor.key, + "Deserialization failed as the given string is not a JSON representation.", + e + ) + } + } + + const ret = fct.apply(thisObj, args) + return ret + } + + public static parseString(value: any, descriptor: IReflectProperty, className: string): string { + const err = Validator.checkString(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + return value + } + + public static parseNumber(value: any, descriptor: IReflectProperty, className: string): number { + const err = Validator.checkNumber(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + return value + } + + public static parseBoolean(value: any, descriptor: IReflectProperty, className: string): boolean { + const err = Validator.checkBoolean(value, descriptor) + if (err) { + throw new ParsingError(className, descriptor.key, err) + } + return value + } + + public static parseArray(value: any[], descriptor: IReflectProperty, className: string, caller: any): any[] { + const err = Validator.checkArray(value, descriptor) + if (err) { + throw new ServalError(err) + } + + const itemDescriptor: any = descriptor.itemDescriptor + const ar: any[] = [] + + for (let i = 0; i < value.length; i++) { + const currentElement = value[i] + try { + if (itemDescriptor.type === "SerializableAsync") { + itemDescriptor.type = "Serializable" + itemDescriptor.typeInfo = caller + } + if (itemDescriptor.typeInfo === Boolean) { + ar.push(this.parseBoolean(currentElement, itemDescriptor, className)) + } else if (itemDescriptor.typeInfo === Number) { + ar.push(this.parseNumber(currentElement, itemDescriptor, className)) + } else if (itemDescriptor.typeInfo === String) { + ar.push(this.parseString(currentElement, itemDescriptor, className)) + } else { + ar.push(this.parseObject(currentElement, itemDescriptor, itemDescriptor.typeInfo, caller)) + } + } catch (e) { + const type = descriptor.parseUnknown ? "fromUnknown" : `to a ${itemDescriptor.typeInfo.name}` + throw new ParsingError( + className, + descriptor.key, + `Item with index ${i} could not be deserialized ${type} (${e.message})`, + e + ) + } + } + + return ar + } + + public static async parseArrayAsync( + value: any[], + descriptor: IReflectProperty, + className: string, + caller: any + ): Promise { + const err = Validator.checkArray(value, descriptor) + if (err) { + throw new ServalError(err) + } + + const itemDescriptor: any = descriptor.itemDescriptor + const ar: any[] = [] + + for (let i = 0; i < value.length; i++) { + const currentElement = value[i] + try { + if (itemDescriptor.typeInfo === Boolean) { + ar.push(this.parseBoolean(currentElement, itemDescriptor, className)) + } else if (itemDescriptor.typeInfo === Number) { + ar.push(this.parseNumber(currentElement, itemDescriptor, className)) + } else if (itemDescriptor.typeInfo === String) { + ar.push(this.parseString(currentElement, itemDescriptor, className)) + } else { + ar.push(await this.parseObjectAsync(currentElement, itemDescriptor, className, caller)) + } + } catch (e) { + const type = descriptor.parseUnknown ? "fromUnknown" : `to a ${itemDescriptor.typeInfo.name}` + throw new ParsingError( + className, + descriptor.key, + `Item with index ${i} could not be deserialized ${type} (${e.message})`, + e + ) + } + } + + return ar + } + + public static parseObject(value: any, descriptor: IReflectProperty, className: string, caller: any): any { + if (value === null || typeof value === "undefined") { + return null + } + const classInfo: any = descriptor.typeInfo + let thisObj: any = classInfo + if (value instanceof classInfo) { + return value + } else if ((typeof value === "string" && descriptor.deserializeStrings) || descriptor.enforceString) { + return Parser.parseStringObject(value, descriptor, className, caller) + } else if (descriptor.any) { + return value + } + let fct: any + const args: any[] = [value] + + if ((descriptor.parseUnknown || descriptor.type === "Serializable") && value && value["@type"]) { + return caller.fromUnknown(value) + } + + if ( + (typeof descriptor.allowSubclasses === "undefined" || descriptor.allowSubclasses) && + value && + value["@type"] + ) { + return caller.fromUnknown(value) + } + + if (descriptor.customParser) { + fct = descriptor.customParser + args.push(descriptor) + args.push(classInfo) + } + if (!fct) { + fct = classInfo.fromJSON + args.push(classInfo) + } + if (!fct) { + fct = classInfo.from + args.push(classInfo) + } + + if (!fct) { + fct = caller.from + thisObj = caller + args.push(caller) + } + + return fct.apply(thisObj, args) + } + + public static async parseObjectAsync( + value: any, + descriptor: IReflectProperty, + className: string, + caller: any + ): Promise { + if (value === null || typeof value === "undefined") { + return await Promise.resolve(null) + } + const classInfo: any = descriptor.typeInfo + let thisObj: any = classInfo + if (value instanceof classInfo) { + return await Promise.resolve(value) + } else if ((typeof value === "string" && descriptor.deserializeStrings) || descriptor.enforceString) { + return await Parser.parseStringObjectAsync(value, descriptor, className, caller) + } else if (descriptor.any) { + return await Promise.resolve(value) + } + let fct: any + const args: any[] = [value] + + if ( + (descriptor.parseUnknown || + descriptor.type === "Serializable" || + descriptor.type === "SerializableAsync") && + value && + value["@type"] + ) { + // eslint-disable-next-line @typescript-eslint/return-await + return await caller.fromUnknown(value) + } + + if ( + (typeof descriptor.allowSubclasses === "undefined" || descriptor.allowSubclasses) && + value && + value["@type"] + ) { + // eslint-disable-next-line @typescript-eslint/return-await + return await caller.fromUnknown(value) + } + + if (descriptor.customParser) { + fct = descriptor.customParser + args.push(descriptor) + args.push(classInfo) + } + if (!fct) { + fct = classInfo.fromJSON + args.push(classInfo) + } + if (!fct) { + fct = classInfo.from + args.push(classInfo) + } + + if (!fct) { + fct = caller.from + thisObj = caller + args.push(caller) + } + + const ret = await fct.apply(thisObj, args) + return ret + } +} diff --git a/src/parsing/ParsingError.ts b/src/parsing/ParsingError.ts new file mode 100644 index 0000000..6f0aaaa --- /dev/null +++ b/src/parsing/ParsingError.ts @@ -0,0 +1,26 @@ +import { ServalError } from "../errors" + +export class ParsingError extends ServalError { + public type: string + public property: string + public reason: string + public cause: Error | undefined + + public constructor(type: string, property: string, reason: string, cause?: Error) { + super(`${type}.${property} :: ${reason}`) + + Object.setPrototypeOf(this, new.target.prototype) + this.name = ParsingError.name + this.type = type + this.property = property + this.reason = reason + this.cause = cause + } + + public toString(): string { + if (this.cause) { + return `${this.type}.${this.property} :: ${this.reason}\n\n${this.cause.stack}` + } + return `${this.type}.${this.property} :: ${this.reason}` + } +} diff --git a/src/reflection/ReflectProperty.ts b/src/reflection/ReflectProperty.ts new file mode 100644 index 0000000..a305943 --- /dev/null +++ b/src/reflection/ReflectProperty.ts @@ -0,0 +1,59 @@ +import { PrimitiveType } from "../validation/ValidateInterfaces" + +export interface IReflectProperty { + /** + * The property's name + */ + key: string + /** + * The TypeScript type of the property (e.g. Classname) + */ + type: string + /** + * The Javascript constructor/class + */ + typeInfo: Function + /** + * The Javascript primitive type of the property + */ + primitiveType?: string + + itemDescriptor?: IReflectProperty + /** + * The possible static value of the property, e.g. @context, @type or @version + */ + value?: any + + serialize?: boolean + + serializeProperty?: boolean + serializeAs?: boolean + + alias?: string + allowSubclasses?: boolean + any?: boolean + customDeserializer?: Function + customGenerator?: Function + customParser?: Function + customSerializer?: Function + deserializeStrings?: boolean + enforceString?: boolean + optional?: boolean + + parseUnknown?: boolean + + allowedTypes?: PrimitiveType[] | PrimitiveType + customValidator?: Function + validate?: boolean + minValue?: number + maxValue?: number + minLength?: number + maxLength?: number + allowedChars?: string + disallowedChars?: string + allowedValues?: any[] + disallowedValues?: any[] + regExp?: RegExp + validateInternal?: Function + requiredInheritance?: Function[][] +} diff --git a/src/reflection/globals.ts b/src/reflection/globals.ts new file mode 100644 index 0000000..e6013f8 --- /dev/null +++ b/src/reflection/globals.ts @@ -0,0 +1,33 @@ +import { SerializableBase } from "../SerializableBase" +import { IReflectProperty } from "./ReflectProperty" + +export const propertyBucketName = "serializableProperties" + +export function getReflectProperty(target: any, propertyKey: string, type = "any"): IReflectProperty { + const constructorDefinition: any = + target.constructor.name !== "Function" ? target.constructor.prototype.constructor : target + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (!SerializableBase.__classes) { + SerializableBase.__classes = new Map() + } + + let propClass = SerializableBase.__classes.get(constructorDefinition.name) + if (!propClass) { + propClass = new Map() + SerializableBase.__classes.set(constructorDefinition.name, propClass) + } + + let propInstance = propClass.get(propertyKey) + if (!propInstance) { + const lowerType = type.toLowerCase() + let primitiveType = "object" + if (lowerType === "boolean" || lowerType === "array" || lowerType === "number" || lowerType === "string") { + primitiveType = lowerType + } + propInstance = { key: propertyKey, type: type, primitiveType: primitiveType, typeInfo: target } + propClass.set(propertyKey, propInstance) + } + + return propInstance +} diff --git a/src/serialization/Serialize.ts b/src/serialization/Serialize.ts new file mode 100644 index 0000000..0ac5aaa --- /dev/null +++ b/src/serialization/Serialize.ts @@ -0,0 +1,164 @@ +import "reflect-metadata" +import { getReflectProperty } from "../reflection/globals" +import { SerializableAsync } from "../SerializableAsync" +import { SerializableBase } from "../SerializableBase" +import { SerializeParameter } from "./SerializeParameter" + +export class Serialize { + public static serialize(params?: SerializeParameter) { + return function (target: any, propertyKey: string): void { + const result = Reflect.getOwnMetadata("design:type", target, propertyKey) + if (!result) { + throw new Error( + `No type information for property ${propertyKey} of class ${target} (constructor ${target.constructor}). This usually happens if you declare classes in one scope, but access them from another scope - try to check your imports if you importing the same class.` + ) + } + + const prop = getReflectProperty(target, propertyKey, result.name) + prop.type = result.name + prop.typeInfo = result + + const lowerType = prop.type.toLowerCase() + if (lowerType === "boolean" || lowerType === "array" || lowerType === "number" || lowerType === "string") { + prop.primitiveType = lowerType + } else { + prop.primitiveType = "object" + } + + let key + switch (prop.type) { + case "Object": + key = "." + break + case "Array": + key = "[]" + break + case "Map": + key = "{}" + break + } + + if (key) { + if (params?.type) { + prop.itemDescriptor = { key: key, type: params.type.name, typeInfo: params.type } + } else { + prop.itemDescriptor = { + key: key, + type: "SerializableAsync", + typeInfo: SerializableAsync, + parseUnknown: true + } + } + } + + if (!params) { + return + } + prop.enforceString = params.enforceString + + if (params.any) { + prop.any = params.any + } + + if (params.deserializeStrings) { + prop.deserializeStrings = params.deserializeStrings + } + + if (params.alias) { + prop.alias = params.alias + } + + if (params.customGenerator) { + prop.customGenerator = params.customGenerator + } + if (params.parseUnknown) { + prop.parseUnknown = params.parseUnknown + } + if (params.customDeserializer) { + prop.customDeserializer = params.customDeserializer + } + if (params.customParser) { + prop.customParser = params.customParser + } + + if (params.optional) { + prop.optional = true + } + } + } +} + +export function schema(context: string, type?: string, version?: string) { + return (target: any): void => { + Reflect.defineMetadata("design:type", String, target, "@context") + Reflect.defineMetadata("design:type", String, target, "@type") + Reflect.defineMetadata("design:type", String, target, "@version") + Reflect.defineMetadata(type ? type : target.constructor.name, target, SerializableBase, "types") + + const propContext = getReflectProperty(target, "@context") + propContext.value = context + + if (type) { + const propType = getReflectProperty(target, "@type") + propType.value = type + } + + if (version) { + const propVersion = getReflectProperty(target, "@version") + propVersion.value = version + } + } +} + +export function type(type: string, version?: string) { + return (target: any): void => { + Reflect.defineMetadata("design:type", String, target, "@context") + Reflect.defineMetadata("design:type", String, target, "@type") + Reflect.defineMetadata("design:type", String, target, "@version") + Reflect.defineMetadata(type, target, SerializableBase, "types") + + const propType = getReflectProperty(target, "@type") + propType.value = type + + if (version) { + const propVersion = getReflectProperty(target, "@version") + propVersion.value = version + } + } +} + +export function version(version: string) { + return (target: any): void => { + Reflect.defineMetadata("design:type", String, target, "@context") + Reflect.defineMetadata("design:type", String, target, "@type") + Reflect.defineMetadata("design:type", String, target, "@version") + Reflect.defineMetadata(type, target, SerializableBase, "types") + + const propVersion = getReflectProperty(target, "@version") + propVersion.value = version + } +} + +export function serializeOnly( + serializeProperty: string, + type: "string" | "number" | "boolean" | "array" | "object" = "object" +) { + return (target: any): void => { + Reflect.defineMetadata("design:type", String, target, "serializeAs") + Reflect.defineMetadata("design:type", String, target, "serializeProperty") + + const serializeAs = getReflectProperty(target, "serializeAs") + serializeAs.value = type + serializeAs.validate = false + serializeAs.serialize = false + + const serializeProp = getReflectProperty(target, "serializeProperty") + serializeProp.value = serializeProperty + serializeProp.validate = false + serializeProp.serialize = false + } +} + +export function serialize(params?: SerializeParameter): any { + return Serialize.serialize(params) +} diff --git a/src/serialization/SerializeParameter.ts b/src/serialization/SerializeParameter.ts new file mode 100644 index 0000000..a8f9c05 --- /dev/null +++ b/src/serialization/SerializeParameter.ts @@ -0,0 +1,87 @@ +import { SerializableBase } from "../SerializableBase" + +export interface SerializeParameter { + /** + * The serialization alias for this property. Serialization and deserialization will + * only work with the alias if set + * @default undefined - no alias is set + */ + alias?: string + + /** + * Whether or not to allow subclasses of defined types + * @default true - Subclasses are allowed + */ + allowSubclasses?: boolean + + /** + * Whether or not the content of a property should be parsed (and validated) + * @default false - the property and its content is parsed and validated + */ + any?: boolean + + /** + * The custom deserialization function to deserialize an object from a string + * @default undefined - the internal .deserialize() function is used + */ + customDeserializer?: + | ((value: string) => SerializableBase) + | ((value: string) => Promise) + | Function + + /** + * The custom function to parse an object from another (usually untyped) JSON object + * @default undefined - the internal .from() function is used + */ + customParser?: ((value: object) => SerializableBase) | ((value: object) => Promise) | Function + + /** + * The custom function to generate a JSON representation out of an object + * @default undefined - the internal .toJSON() function is used + */ + customGenerator?: ((value: SerializableBase) => object) | Function + + /** + * The custom function to serialize an object to a string + * @default undefined - the internal .serialize() function is used + */ + customSerializer?: ((value: SerializableBase) => string) | Function + + /** + * Whether or not strings should be serialized + * Only works if strings are NOT allowed as types (as otherwise + * it uses the string as value and not the deserialized object) + */ + deserializeStrings?: boolean + + /** + * Whether or not to enforce string (de-)serialization for this property + * @default false - Strings are not enforces, the properties type is used + */ + enforceString?: boolean + + /** + * Whether or not the property can be optional (not existing in the structure) + * Same as validate.nullable + * @default false - the property must be set + */ + optional?: boolean + + /** + * The type information of the given property. This can be fetched automatically be the source + * code - with following exceptions: + * - `type` needs to be set for Arrays + * + * @default undefined - no type is set, type will be used from the reflection + */ + type?: Function + + /** + * Whether or not the property's value should be parsed as unknown. This is only done if the value + * and its @type property is set. + * + * @default undefined - By default, types of Serializable and SerializableAsync are parsed as unknown. Additionally, + * if subclasses are allowed, they are parsed as unknown. + */ + parseUnknown?: boolean +} diff --git a/src/validation/Validate.ts b/src/validation/Validate.ts new file mode 100644 index 0000000..58233c5 --- /dev/null +++ b/src/validation/Validate.ts @@ -0,0 +1,234 @@ +import "reflect-metadata" +import { DecoratorError } from "../errors" +import { getReflectProperty, propertyBucketName } from "../reflection/globals" +import { Validator } from "../validation/Validator" +import { PrimitiveType, ValidateParameter } from "./ValidateInterfaces" +import { ValidationError } from "./ValidationError" + +export type ValidatorFunction = (target: any, propertyKey: string) => void + +export class Validate { + public static validate(params?: ValidateParameter): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + prop.validate = true + + const propertyGetter = function (): any { + if (prop.value && typeof this[`_${propertyKey}`] === "undefined") { + return prop.value + } + return this[`_${propertyKey}`] + } + + const propertySetter = function (newVal: any): void { + let err = Validator.checkProperty(newVal, prop) + if (err) { + throw new ValidationError(this.constructor.name, `${prop.key}:${prop.type}`, err) + } + if (params?.customValidator) { + err = params.customValidator.apply(this, [newVal, prop]) + if (err) { + throw new ValidationError(this.constructor.name, `${prop.key}:${prop.type}`, err) + } + } + + this[`_${propertyKey}`] = newVal + } + + if (delete target[propertyKey]) { + Reflect.defineMetadata(propertyBucketName, [prop], target) + + // Create new property with getter and setter + Object.defineProperty(target, propertyKey, { + get: propertyGetter, + set: propertySetter, + enumerable: true, + configurable: true + }) + } + + if (!params) { + return + } + prop.optional = params.nullable ? true : false + prop.customValidator = params.customValidator + switch (prop.type) { + case "Object": + prop.allowedValues = params.allowedValues + prop.disallowedValues = params.disallowedValues + prop.minLength = params.min + prop.maxLength = params.max + prop.allowedTypes = params.allowedTypes + break + + case "String": + prop.minLength = params.min + prop.maxLength = params.max + prop.allowedChars = params.allowedChars + prop.disallowedChars = params.disallowedChars + prop.regExp = params.regExp + prop.allowedValues = params.allowedValues + prop.disallowedValues = params.disallowedValues + break + + case "Number": + prop.minValue = params.min + prop.maxValue = params.max + prop.allowedValues = params.allowedValues + prop.disallowedValues = params.disallowedValues + break + } + } + } + + public static nullable(): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + prop.validate = true + prop.optional = true + } + } + + public static minLength(minLength: number): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "String") { + throw new DecoratorError( + "minLength", + `Decorator minLength only works on String types: Property ${propertyKey} of class ${target.constructor.name} is not of type String.` + ) + } + if (minLength < 0) { + throw new DecoratorError( + "minLength", + `Decorator minLength cannot be negative: Property ${propertyKey} of class ${target.constructor.name}.` + ) + } + prop.validate = true + prop.minLength = minLength + } + } + + public static maxLength(maxLength: number): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "String") { + throw new DecoratorError( + "maxLength", + `Decorator maxLength only works on String types: Property ${propertyKey} of class ${target.constructor.name} is not of type String.` + ) + } + prop.validate = true + prop.maxLength = maxLength + } + } + + public static allowedChars(allowedChars: string): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "String") { + throw new DecoratorError( + "allowedChars", + `Decorator allowedChars only works on String types: Property ${propertyKey} of class ${target.constructor.name} is not of type String.` + ) + } + prop.validate = true + prop.allowedChars = allowedChars + } + } + + public static disallowedChars(disallowedChars: string): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "String") { + throw new DecoratorError( + "disallowedChars", + `Decorator disallowedChars only works on String types: Property ${propertyKey} of class ${target.constructor.name} is not of type String.` + ) + } + prop.validate = true + prop.disallowedChars = disallowedChars + } + } + + public static allowedValues(allowedValues: any[]): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + prop.validate = true + prop.allowedValues = allowedValues + } + } + + public static disallowedValues(disallowedValues: any[]): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + prop.validate = true + prop.disallowedValues = disallowedValues + } + } + + public static regExp(regExp: RegExp): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "String") { + throw new DecoratorError( + "regExp", + `Decorator regExp only works on String types: Property ${propertyKey} of class ${target.constructor.name} is not of type String.` + ) + } + prop.validate = true + prop.regExp = regExp + } + } + + public static allowedTypes(allowedTypes: PrimitiveType[] | PrimitiveType): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + prop.validate = true + prop.allowedTypes = allowedTypes + } + } + + public static minValue(minValue: number): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "Number") { + throw new DecoratorError( + "minValue", + `Decorator minValue only works on Number types: Property ${propertyKey} of class ${target.constructor.name} is not of type Number.` + ) + } + prop.validate = true + prop.minValue = minValue + } + } + + public static maxValue(maxValue: number): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "Number") { + throw new DecoratorError( + "maxValue", + `Decorator maxValue only works on Number types: Property ${propertyKey} of class ${target.constructor.name} is not of type Number.` + ) + } + prop.validate = true + prop.maxValue = maxValue + } + } + + public static between(minValue: number, maxValue: number): ValidatorFunction { + return function (target: any, propertyKey: string): void { + const prop = getReflectProperty(target, propertyKey) + if (prop.type !== "Number") { + throw new DecoratorError( + "between", + `Decorator between only works on Number types: Property ${propertyKey} of class ${target.constructor.name} is not of type Number.` + ) + } + prop.validate = true + prop.minValue = minValue + prop.maxValue = maxValue + } + } +} diff --git a/src/validation/ValidateGlobals.ts b/src/validation/ValidateGlobals.ts new file mode 100644 index 0000000..95af2e9 --- /dev/null +++ b/src/validation/ValidateGlobals.ts @@ -0,0 +1,55 @@ +import { ValidatorFunction } from ".." +import { Validate } from "./Validate" +import { PrimitiveType, ValidateParameter } from "./ValidateInterfaces" + +export function nullable(): ValidatorFunction { + return Validate.nullable() +} + +export function validate(params?: ValidateParameter): ValidatorFunction { + return Validate.validate(params) +} + +export function minLength(minLength: number): ValidatorFunction { + return Validate.minLength(minLength) +} + +export function maxLength(maxLength: number): ValidatorFunction { + return Validate.maxLength(maxLength) +} + +export function allowedChars(allowedChars: string): ValidatorFunction { + return Validate.allowedChars(allowedChars) +} + +export function disallowedChars(disallowedChars: string): ValidatorFunction { + return Validate.disallowedChars(disallowedChars) +} + +export function allowedValues(allowedValues: any[]): ValidatorFunction { + return Validate.allowedValues(allowedValues) +} + +export function disallowedValues(disallowedValues: any[]): ValidatorFunction { + return Validate.disallowedValues(disallowedValues) +} + +export function regExp(regExp: RegExp): ValidatorFunction { + return Validate.regExp(regExp) +} + +export function allowedTypes(types: PrimitiveType[] | PrimitiveType): ValidatorFunction { + return Validate.allowedTypes(types) +} + +export function minValue(minValue: number): ValidatorFunction { + return Validate.minValue(minValue) +} + +export function maxValue(maxValue: number): ValidatorFunction { + return Validate.maxValue(maxValue) +} + +export function between(minValue: number, maxValue: number): ValidatorFunction { + return Validate.between(minValue, maxValue) +} diff --git a/src/validation/ValidateInterfaces.ts b/src/validation/ValidateInterfaces.ts new file mode 100644 index 0000000..e4f1656 --- /dev/null +++ b/src/validation/ValidateInterfaces.ts @@ -0,0 +1,97 @@ +export enum PrimitiveType { + Number = "number", + Object = "object", + Boolean = "boolean", + String = "string", + Array = "array" +} + +export interface ValidateParameter { + /** + * Whether or not the property needs to be set / is required. + * @default false - The property is required and must be set + */ + nullable?: boolean + + /** + * The minimum allowed value (inclusive). + * If the corresponding type is a number, the min value is the minimum allowed numeric value. + * If the corresponding type is a string, the min value is the minimum allowed length of the string. + * @default undefined - No minimum value is set + */ + min?: number + + /** + * The maximum allowed value (inclusive). + * If the corresponding type is a number, the max value is the maximum allowed numeric value. + * If the corresponding type is a string, the max value is the maximum allowed length of the string. + * @default undefined - No maximum value is set + */ + max?: number + + /** + * A character string of allowed characters. Each character should be unique. + * If the corresponding type is a string, only the characters within the allowed string are allowed. + * @default undefined - All characters are allowed + */ + allowedChars?: string + + /** + * A character string of disallowed characters. Each character should be unique. + * If the corresponding type is a string, no character of the disallowed string is allowed. + * @default undefined - No character is disallowed + */ + disallowedChars?: string + + /** + * An array of allowed values. The value must be one of the allowedValues. + * @default undefined - All values are allowed + */ + allowedValues?: any[] + + /** + * An array of disallowed values. The value must not be one of the disallowedValues. + * @default undefined - No values are disallowed + */ + disallowedValues?: any[] + + /** + * A Regular expression on which the given string is tested against. + * @default undefined - No regular expression will be tested + */ + regExp?: RegExp + + /** + * An array which primitive JavaScript types are allowed as a value or a + * string with a single allowed type. + * If not set, it uses the type defined by the property's TypeScript definition. + * Caution: If the type definition is not a primitive type (like an Interface, Class + * Union Operator, Array, Template, etc) the generic type "object" is used as a fallback). + * @default undefined - uses the typescript type definition of the property ("object" if unclear) + */ + allowedTypes?: PrimitiveType[] | PrimitiveType + + /** + * An array of required inheritances of an object. The objects of this array + * are again arrays of class names. The first array is an OR the second array is + * an AND. + * + * Example: + * [ + * [TokenRelationshipTemplate, Token, CoreSerializableAsync, SerializableAsync], + * [File, CoreSerializableAsync, SerializableAsync] + * ] + * + * @default undefined + */ + requiredInheritance?: Function[][] + + /** + * A function can be used for custom validation. The custom validator function will be called + * *in addition* to all other validators. + * @param value The value which should be set + * @returns {(string|undefined)} Returns a string (with the error message) if an error occured, undefined otherwise. + * @default undefined - No custom validation is done. + */ + customValidator?(value: any): string | undefined +} diff --git a/src/validation/ValidationError.ts b/src/validation/ValidationError.ts new file mode 100644 index 0000000..f54fa72 --- /dev/null +++ b/src/validation/ValidationError.ts @@ -0,0 +1,26 @@ +import { ServalError } from "../errors" + +export class ValidationError extends ServalError { + public type: string + public property: string + public reason: string + public cause: Error | undefined + + public constructor(type: string, property: string, reason: string, cause?: Error) { + super(`${type}.${property} :: ${reason}`) + + Object.setPrototypeOf(this, new.target.prototype) + this.name = ValidationError.name + this.type = type + this.property = property + this.reason = reason + this.cause = cause + } + + public toString(): string { + if (this.cause) { + return `${this.type}.${this.property} :: ${this.reason}\n\n${this.cause.stack}` + } + return `${this.type}.${this.property} :: ${this.reason}` + } +} diff --git a/src/validation/Validator.ts b/src/validation/Validator.ts new file mode 100644 index 0000000..2ea37bf --- /dev/null +++ b/src/validation/Validator.ts @@ -0,0 +1,232 @@ +import { IReflectProperty } from "../reflection/ReflectProperty" +import { PrimitiveType } from "./ValidateInterfaces" + +export abstract class Validator { + public static checkDefined(value: any, _descriptor?: IReflectProperty): string | undefined { + // eslint-disable-next-line use-isnan + if (typeof value === "undefined" || value === null || value === NaN) { + return "Value is not defined" + } + return + } + + public static checkBoolean(value: boolean, _descriptor?: IReflectProperty): string | undefined { + if (typeof value !== "boolean") { + return "Value is not a boolean" + } + return + } + + public static checkString(value: string, descriptor: IReflectProperty): string | undefined { + if (typeof value !== "string") { + return "Value is not a string" + } + + if (typeof descriptor.minLength !== "undefined" && value.length < descriptor.minLength) { + return `Value is shorter than ${descriptor.minLength} characters` + } + + if (typeof descriptor.maxLength !== "undefined" && value.length > descriptor.maxLength) { + return `Value is longer than ${descriptor.maxLength} characters` + } + + if (typeof descriptor.regExp !== "undefined" && !descriptor.regExp.test(value)) { + return `Value does not match regular expression ${descriptor.regExp}` + } + + if (typeof descriptor.allowedChars !== "undefined") { + const regExp = new RegExp(`^[${descriptor.allowedChars}]+$`) + if (!regExp.test(value)) { + return `Value contains other characters than the allowed ones '${descriptor.allowedChars}'` + } + } + + if (typeof descriptor.disallowedChars !== "undefined") { + const regExp = new RegExp(`[${descriptor.disallowedChars}]+`) + if (regExp.test(value)) { + return `Value contains disallowed characters like '${descriptor.disallowedChars}'` + } + } + + if (typeof descriptor.allowedValues !== "undefined" && !descriptor.allowedValues.includes(value)) { + return "Value is not within the list of allowed values." + } + + if (typeof descriptor.disallowedValues !== "undefined" && descriptor.disallowedValues.includes(value)) { + return "Value is within the list of disallowed values." + } + + return + } + + public static checkNumber(value: number, descriptor: IReflectProperty): string | undefined { + if (typeof value !== "number") { + return "Value is not a number." + } + + if (isNaN(value)) { + return "Value could not be parsed to Number" + } + + if (typeof descriptor.minValue !== "undefined" && value < descriptor.minValue) { + return `Value is below threshold of ${descriptor.minValue}` + } + + if (typeof descriptor.maxValue !== "undefined" && value > descriptor.maxValue) { + return `Value is above threshold of ${descriptor.maxValue}` + } + + if (typeof descriptor.allowedValues !== "undefined" && !descriptor.allowedValues.includes(value)) { + return "Value is not within the list of allowed values." + } + + if (typeof descriptor.disallowedValues !== "undefined" && descriptor.disallowedValues.includes(value)) { + return "Value is within the list of disallowed values." + } + + return + } + + public static checkArray(value: any, descriptor: IReflectProperty): string | undefined { + if (typeof value !== "object" || !(value instanceof Array)) { + return "Value is not an Array." + } + + if (typeof descriptor.minLength !== "undefined" && value.length < descriptor.minLength) { + return `Array has less items than minimum ${descriptor.minLength} allowed.` + } + + if (typeof descriptor.maxLength !== "undefined" && value.length > descriptor.maxLength) { + return `Array has more items than maximum ${descriptor.maxLength} allowed.` + } + + let i = 0 + for (const item of value) { + if (typeof descriptor.allowedValues !== "undefined" && !descriptor.allowedValues.includes(item)) { + return `Value of item ${i} is not within the list of allowed values.` + } + + if (typeof descriptor.disallowedValues !== "undefined" && descriptor.disallowedValues.includes(item)) { + return `Value of item ${i} is within the list of disallowed values.` + } + i++ + } + + return + } + + public static checkObject(value: any, descriptor: IReflectProperty): string | undefined { + if (descriptor.any) { + return "" + } + if (typeof value !== "object") { + return `Value is not an Object and no instance of ${descriptor.typeInfo.name}.` + } + if (descriptor.primitiveType === "object") { + if ( + !(value instanceof descriptor.typeInfo) && + !(descriptor.typeInfo.name === "Serializable" || descriptor.typeInfo.name === "SerializableAsync") + ) { + return `Value not an instance of ${descriptor.typeInfo.name}.` + } + } + + if (descriptor.requiredInheritance) { + let notFound = true + for (const classes of descriptor.requiredInheritance) { + let i = 0 + for (const instance of classes) { + if (value instanceof instance) { + i++ + } + } + if (i === classes.length - 1) { + notFound = false + break + } + } + if (notFound) { + return `Value does not fit into any given inheritance chains for value ${descriptor.typeInfo.name}` + } + } + return + } + + public static checkTypes(value: any, descriptor: IReflectProperty): string | undefined { + const allowedTypes = descriptor.allowedTypes + if (!allowedTypes) { + return + } + for (const type of allowedTypes) { + if (type.toLowerCase() === "array" && Array.isArray(value)) { + return + } else if (typeof value === type.toLowerCase()) { + return + } + } + return "Value is not an allowed type." + } + + public static checkProperty(value: any, descriptor: IReflectProperty): string | undefined { + // *****CAUTION: Check Parser.parseProperty if you make changes here!***** + if (!descriptor.validate) { + return + } + + let err: string | undefined + + if (!descriptor.optional) { + err = this.checkDefined(value, descriptor) + if (err) return err + // eslint-disable-next-line use-isnan + } else if (typeof value === "undefined" || value === null || value === NaN) { + return + } + + err = this.checkTypes(value, descriptor) + if (err) return err + + if (typeof descriptor.customValidator === "function") { + err = descriptor.customValidator(value, descriptor) + if (err) return err + } + + if (!descriptor.type) descriptor.type = "object" + + switch (descriptor.primitiveType) { + case "array": + return this.checkArray(value, descriptor) + + case "boolean": + return this.checkBoolean(value, descriptor) + + case "number": + return this.checkNumber(value, descriptor) + + case "string": + return this.checkString(value, descriptor) + default: + // Ignore all other values + break + } + + // Check possible union types + if (descriptor.allowedTypes) { + if (typeof value === "boolean" && descriptor.allowedTypes.includes(PrimitiveType.Boolean)) { + return this.checkBoolean(value, descriptor) + } else if (typeof value === "number" && descriptor.allowedTypes.includes(PrimitiveType.Number)) { + return this.checkNumber(value, descriptor) + } else if ( + typeof value === "string" && + !descriptor.deserializeStrings && + descriptor.allowedTypes.includes(PrimitiveType.String) + ) { + return this.checkString(value, descriptor) + } else if (Array.isArray(value) && descriptor.allowedTypes.includes(PrimitiveType.Array)) { + return this.checkArray(value, descriptor) + } + } + + return this.checkObject(value, descriptor) + } +} diff --git a/src/wrapper/JSONWrapper.ts b/src/wrapper/JSONWrapper.ts new file mode 100644 index 0000000..d662093 --- /dev/null +++ b/src/wrapper/JSONWrapper.ts @@ -0,0 +1,22 @@ +import { Serializable } from "../Serializable" +import { serialize, serializeOnly, type } from "../serialization/Serialize" +import { validate } from "../validation/ValidateGlobals" + +@type("JSONWrapper") +@serializeOnly("value") +export class JSONWrapper extends Serializable { + @serialize({ any: true }) + @validate() + public value: any + + public static from(value: any): JSONWrapper { + delete value["@type"] + const parsed = JSON.parse(JSON.stringify(value)) + return this.fromT({ value: parsed }, JSONWrapper) + } + + public static deserialize(value: string): JSONWrapper { + const parsed = JSON.parse(value) + return this.fromT({ value: parsed }, JSONWrapper) + } +} diff --git a/src/wrapper/JSONWrapperAsync.ts b/src/wrapper/JSONWrapperAsync.ts new file mode 100644 index 0000000..4b57357 --- /dev/null +++ b/src/wrapper/JSONWrapperAsync.ts @@ -0,0 +1,22 @@ +import { SerializableAsync } from "../SerializableAsync" +import { serialize, serializeOnly, type } from "../serialization/Serialize" +import { validate } from "../validation/ValidateGlobals" + +@type("JSONWrapperAsync") +@serializeOnly("value") +export class JSONWrapperAsync extends SerializableAsync { + @serialize({ any: true }) + @validate() + public value: any + + public static async from(value: any): Promise { + delete value["@type"] + const parsed = JSON.parse(JSON.stringify(value)) + return await this.fromT({ value: parsed }, JSONWrapperAsync) + } + + public static async deserialize(value: string): Promise { + const parsed = JSON.parse(value) + return await this.fromT({ value: parsed }, JSONWrapperAsync) + } +} diff --git a/test/data/consumption/Attribute.ts b/test/data/consumption/Attribute.ts new file mode 100644 index 0000000..3f9e759 --- /dev/null +++ b/test/data/consumption/Attribute.ts @@ -0,0 +1,26 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CoreSerializable, ICoreSerializable } from "../core/CoreSerializable" + +export interface IAttribute extends ICoreSerializable { + name: string + value: any + validFrom?: string +} + +@schema("https://schema.local.corp", "Attribute") +export class Attribute extends CoreSerializable implements IAttribute { + @validate() + @serialize() + public name: string + + @serialize({ any: true }) + public value: any + + @validate({ nullable: true }) + @serialize() + public validFrom?: string + + public static from(value: IAttribute): Attribute { + return super.fromT(value, Attribute) + } +} diff --git a/test/data/consumption/BetterAttribute.ts b/test/data/consumption/BetterAttribute.ts new file mode 100644 index 0000000..b71c110 --- /dev/null +++ b/test/data/consumption/BetterAttribute.ts @@ -0,0 +1,17 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { Attribute, IAttribute } from "./Attribute" + +export interface IBetterAttribute extends IAttribute { + validTo?: string +} + +@schema("https://schema.local.corp", "BetterAttribute") +export class BetterAttribute extends Attribute implements IBetterAttribute { + @validate({ nullable: true }) + @serialize() + public validTo?: string + + public static from(value: IBetterAttribute): BetterAttribute { + return super.fromT(value, BetterAttribute) + } +} diff --git a/test/data/consumption/Draft.ts b/test/data/consumption/Draft.ts new file mode 100644 index 0000000..cd5ddb7 --- /dev/null +++ b/test/data/consumption/Draft.ts @@ -0,0 +1,39 @@ +import { ISerializableAsync, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { CoreSynchronizable, ICoreSynchronizable } from "../core/CoreSynchronizable" +import { CoreDate, ICoreDate } from "../core/types/CoreDate" +import { CoreId } from "../core/types/CoreId" + +export interface IDraftSerialized extends ICoreSynchronizable { + type: string + createdAt: ICoreDate + content: ISerializableAsync +} + +@schema("https://schema.corp", "Draft") +export class Draft extends CoreSynchronizable implements IDraftSerialized { + @validate() + @serialize() + public id: CoreId + + @validate() + @serialize() + public type: string + + @validate() + @serialize() + public createdAt: CoreDate + + @validate() + @serialize() + public content: SerializableAsync + + public static async from(value: IDraftSerialized | Draft): Promise { + return await super.fromT(value, Draft) + } + + public objectIdentifier(): string { + return JSON.stringify({ + id: this.id.toString() + }) + } +} diff --git a/test/data/consumption/RelationshipAttribute.ts b/test/data/consumption/RelationshipAttribute.ts new file mode 100644 index 0000000..9aad594 --- /dev/null +++ b/test/data/consumption/RelationshipAttribute.ts @@ -0,0 +1,18 @@ +import { ISerializableAsync, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { IRelationshipAttributeHistoryItem, RelationshipAttributeHistoryItem } from "./RelationshipAttributeHistoryItem" + +export interface IRelationshipAttribute extends ISerializableAsync { + current: any + history: IRelationshipAttributeHistoryItem[] +} + +@schema("https://schema.corp", "RelationshipAttribute") +export class RelationshipAttribute extends SerializableAsync implements IRelationshipAttribute { + @validate() + @serialize() + public current: any + + @validate() + @serialize({ type: RelationshipAttributeHistoryItem }) + public history: RelationshipAttributeHistoryItem[] +} diff --git a/test/data/consumption/RelationshipAttributeHistoryItem.ts b/test/data/consumption/RelationshipAttributeHistoryItem.ts new file mode 100644 index 0000000..a93023e --- /dev/null +++ b/test/data/consumption/RelationshipAttributeHistoryItem.ts @@ -0,0 +1,31 @@ +import { ISerializableAsync, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { CoreAddress } from "../core/types/CoreAddress" +import { CoreDate } from "../core/types/CoreDate" +import { CoreId, ICoreId } from "../core/types/CoreId" +import { Attribute } from "./Attribute" + +export interface IRelationshipAttributeHistoryItem extends ISerializableAsync { + reference?: ICoreId + changedBy?: CoreAddress + changedAt: CoreDate + attribute: Attribute +} + +@schema("https://schema.corp", "RelationshipAttributeHistoryItem") +export class RelationshipAttributeHistoryItem extends SerializableAsync implements IRelationshipAttributeHistoryItem { + @validate({ nullable: true }) + @serialize() + public reference?: CoreId + + @validate() + @serialize() + public changedAt: CoreDate + + @validate({ nullable: true }) + @serialize() + public changedBy?: CoreAddress + + @validate() + @serialize() + public attribute: Attribute +} diff --git a/test/data/consumption/RelationshipMetadata.ts b/test/data/consumption/RelationshipMetadata.ts new file mode 100644 index 0000000..b8f5379 --- /dev/null +++ b/test/data/consumption/RelationshipMetadata.ts @@ -0,0 +1,39 @@ +import { ISerializableAsync, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { CoreId, ICoreId } from "../core/types/CoreId" +import { RelationshipAttribute } from "./RelationshipAttribute" + +export interface IRelationshipMetadata extends ISerializableAsync { + relationshipId: ICoreId + isPinned: boolean + title: string + description?: string + attributesSent: Record + attributesReceived: Record +} + +@schema("https://schema.corp", "RelationshipMetadata") +export class RelationshipMetadata extends SerializableAsync implements IRelationshipMetadata { + @validate() + @serialize() + public relationshipId: CoreId + + @validate() + @serialize() + public isPinned: boolean + + @validate() + @serialize() + public title: string + + @validate({ nullable: true }) + @serialize() + public description?: string + + @validate() + @serialize() + public attributesSent: Record + + @validate() + @serialize() + public attributesReceived: Record +} diff --git a/test/data/core/CachedMessage.ts b/test/data/core/CachedMessage.ts new file mode 100644 index 0000000..8ec9df2 --- /dev/null +++ b/test/data/core/CachedMessage.ts @@ -0,0 +1,51 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" +import { IMessageContent, MessageContent } from "./MessageContent" +import { IMessageEnvelopeRecipient, MessageEnvelopeRecipient } from "./MessageEnvelopeRecipient" +import { CoreAddress, ICoreAddress } from "./types/CoreAddress" +import { CoreDate, ICoreDate } from "./types/CoreDate" +import { CoreId, ICoreId } from "./types/CoreId" + +export interface ICachedMessage extends ICoreSerializableAsync { + createdBy: ICoreAddress + createdByDevice: ICoreId + + recipients: IMessageEnvelopeRecipient[] + + createdAt: ICoreDate + + attachments?: ICoreId[] + + content: IMessageContent +} + +@schema("https://schema.corp", "CachedMessage") +export class CachedMessage extends CoreSerializableAsync implements ICachedMessage { + @validate() + @serialize() + public createdBy: CoreAddress + + @validate() + @serialize() + public createdByDevice: CoreId + + @validate() + @serialize({ type: MessageEnvelopeRecipient }) + public recipients: MessageEnvelopeRecipient[] + + @validate() + @serialize() + public createdAt: CoreDate + + @validate({ nullable: true }) + @serialize({ type: CoreId }) + public attachments: CoreId[] + + @validate() + @serialize() + public content: MessageContent + + public static async from(value: ICachedMessage): Promise { + return await super.fromT(value, CachedMessage) + } +} diff --git a/test/data/core/Certificate.ts b/test/data/core/Certificate.ts new file mode 100644 index 0000000..dd93fc7 --- /dev/null +++ b/test/data/core/Certificate.ts @@ -0,0 +1,44 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CryptoSignature, ICryptoSignature } from "../crypto/CryptoSignature" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" + +export interface ICertificate extends ICoreSerializableAsync { + content: string + signature: ICryptoSignature +} + +/** + * A Certificate is digitally signed data which is issued by one user A (issuer) for another user B (subject). + * The subject is eligible to share the certificate to any other user C, who in turn can verify, if the information + * provided really comes from user A. Certificates always contain structured data, thus it is machine readable and + * can be used for automatic checks. + * + * The content of a certificate is comparable with standardized SSL/TLS certificates, but they are not compatible + * with each other. However, the content can be transformed. + * + * + */ +@schema("https://schema.corp", "Certificate") +export class Certificate extends CoreSerializableAsync { + /** + * The content of the certificate + */ + @validate() + @serialize() + public content: string + + /** + * The digital signature of the whole content from the issuer. + */ + @validate() + @serialize() + public signature: CryptoSignature + + public static async from(value: ICertificate): Promise { + return await super.fromT(value, Certificate) + } + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, Certificate) + } +} diff --git a/test/data/core/CoreSerializable.ts b/test/data/core/CoreSerializable.ts new file mode 100644 index 0000000..c9debeb --- /dev/null +++ b/test/data/core/CoreSerializable.ts @@ -0,0 +1,6 @@ +import { ISerializable, Serializable, type } from "@js-soft/ts-serval" + +export interface ICoreSerializable extends ISerializable {} + +@type("CoreSerializable") +export class CoreSerializable extends Serializable implements ISerializable {} diff --git a/test/data/core/CoreSerializableAsync.ts b/test/data/core/CoreSerializableAsync.ts new file mode 100644 index 0000000..33e9a76 --- /dev/null +++ b/test/data/core/CoreSerializableAsync.ts @@ -0,0 +1,6 @@ +import { ISerializableAsync, schema, SerializableAsync } from "@js-soft/ts-serval" + +export interface ICoreSerializableAsync extends ISerializableAsync {} + +@schema("https://schema.corp", "CoreSerializableAsync") +export class CoreSerializableAsync extends SerializableAsync implements ISerializableAsync {} diff --git a/test/data/core/CoreSynchronizable.ts b/test/data/core/CoreSynchronizable.ts new file mode 100644 index 0000000..37be735 --- /dev/null +++ b/test/data/core/CoreSynchronizable.ts @@ -0,0 +1,10 @@ +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" + +export interface ICoreSynchronizable extends ICoreSerializableAsync { + synchronizedKeys: string[] + objectIdentifier(): string +} +export abstract class CoreSynchronizable extends CoreSerializableAsync { + public synchronizedKeys: string[] = [] + abstract objectIdentifier(): string +} diff --git a/test/data/core/Mail.ts b/test/data/core/Mail.ts new file mode 100644 index 0000000..a10a588 --- /dev/null +++ b/test/data/core/Mail.ts @@ -0,0 +1,41 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { IMessageContent, MessageContent } from "./MessageContent" +import { CoreAddress, ICoreAddress } from "./types/CoreAddress" + +export interface IMail extends IMessageContent { + to: ICoreAddress[] + cc?: ICoreAddress[] + subject: string + body: string +} + +@schema("https://schema.corp", "Mail") +export class Mail extends MessageContent implements IMail { + @validate() + @serialize({ type: CoreAddress }) + public to: CoreAddress[] + + @validate({ nullable: true }) + @serialize({ type: CoreAddress }) + public cc: CoreAddress[] = [] + + @validate() + @serialize() + public subject: string + + @validate() + @serialize() + public body: string + + public static async from(value: IMail): Promise { + if (typeof value.cc === "undefined") { + value.cc = [] + } + if (typeof value.body === "undefined" && (value as any).content) { + value.body = (value as any).content + delete (value as any).content + } + const obj: Mail = await super.fromT(value, Mail) + return obj + } +} diff --git a/test/data/core/Message.ts b/test/data/core/Message.ts new file mode 100644 index 0000000..174c09e --- /dev/null +++ b/test/data/core/Message.ts @@ -0,0 +1,63 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CryptoSecretKey, ICryptoSecretKey } from "../crypto/CryptoSecretKey" +import { CachedMessage, ICachedMessage } from "./CachedMessage" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" +import { CoreDate, ICoreDate } from "./types/CoreDate" +import { CoreId, ICoreId } from "./types/CoreId" + +export interface IMessage extends ICoreSerializableAsync { + id: ICoreId + secretKey: ICryptoSecretKey + isOwn: boolean + cache?: ICachedMessage + cachedAt?: ICoreDate + metadata?: any + metadataChangedAt?: ICoreDate +} + +@schema("https://schema.corp", "Message") +export class Message extends CoreSerializableAsync implements IMessage { + @validate() + @serialize() + public id: CoreId + + @validate() + @serialize() + public secretKey: CryptoSecretKey + + @validate() + @serialize() + public isOwn: boolean + + @validate({ nullable: true }) + @serialize() + public cache?: CachedMessage + + @validate({ nullable: true }) + @serialize() + public cachedAt?: CoreDate + + @validate({ nullable: true }) + @serialize() + public metadata?: any + + @validate({ nullable: true }) + @serialize() + public metadataChangedAt?: CoreDate + + public objectIdentifier(): string { + return JSON.stringify({ + id: this.id.toString() + }) + } + + public static async from(value: IMessage): Promise { + return await super.fromT(value, Message) + } + + public clearCache(): this { + this.cache = undefined + this.cachedAt = undefined + return this + } +} diff --git a/test/data/core/MessageContent.ts b/test/data/core/MessageContent.ts new file mode 100644 index 0000000..09f9e0a --- /dev/null +++ b/test/data/core/MessageContent.ts @@ -0,0 +1,7 @@ +import { schema } from "@js-soft/ts-serval" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" + +export interface IMessageContent extends ICoreSerializableAsync {} + +@schema("https://schema.corp", "MessageContent") +export abstract class MessageContent extends CoreSerializableAsync implements IMessageContent {} diff --git a/test/data/core/MessageEnvelopeRecipient.ts b/test/data/core/MessageEnvelopeRecipient.ts new file mode 100644 index 0000000..def1300 --- /dev/null +++ b/test/data/core/MessageEnvelopeRecipient.ts @@ -0,0 +1,24 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CryptoCipher, ICryptoCipher } from "../crypto/CryptoCipher" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" +import { CoreAddress, ICoreAddress } from "./types/CoreAddress" + +export interface IMessageEnvelopeRecipient extends ICoreSerializableAsync { + address: ICoreAddress + encryptedKey: ICryptoCipher +} + +@schema("https://schema.corp", "MessageEnvelopeRecipient") +export class MessageEnvelopeRecipient extends CoreSerializableAsync implements IMessageEnvelopeRecipient { + @validate() + @serialize() + public address: CoreAddress + + @validate() + @serialize() + public encryptedKey: CryptoCipher + + public static async from(value: IMessageEnvelopeRecipient): Promise { + return await super.fromT(value, MessageEnvelopeRecipient) + } +} diff --git a/test/data/core/TokenContent.ts b/test/data/core/TokenContent.ts new file mode 100644 index 0000000..c5fdc83 --- /dev/null +++ b/test/data/core/TokenContent.ts @@ -0,0 +1,7 @@ +import { schema } from "@js-soft/ts-serval" +import { CoreSerializableAsync, ICoreSerializableAsync } from "./CoreSerializableAsync" + +export interface ITokenContent extends ICoreSerializableAsync {} + +@schema("https://schema.corp", "TokenContent") +export class TokenContent extends CoreSerializableAsync implements ITokenContent {} diff --git a/test/data/core/TokenContentGeneric.ts b/test/data/core/TokenContentGeneric.ts new file mode 100644 index 0000000..6d6877b --- /dev/null +++ b/test/data/core/TokenContentGeneric.ts @@ -0,0 +1,21 @@ +import { ISerializableAsync, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { ITokenContent, TokenContent } from "./TokenContent" + +export interface ITokenContentGeneric extends ITokenContent { + content: ISerializableAsync +} + +@schema("https://schema.corp", "TokenContentGeneric") +export class TokenContentGeneric extends TokenContent { + @validate() + @serialize() + public content: SerializableAsync + + public static async from(value: ITokenContentGeneric): Promise { + return await super.fromT(value, TokenContentGeneric) + } + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentGeneric) + } +} diff --git a/test/data/core/TokenContentRelationshipTemplate.ts b/test/data/core/TokenContentRelationshipTemplate.ts new file mode 100644 index 0000000..6fc64d9 --- /dev/null +++ b/test/data/core/TokenContentRelationshipTemplate.ts @@ -0,0 +1,28 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { CryptoSecretKey, ICryptoSecretKey } from "../crypto/CryptoSecretKey" +import { ITokenContent, TokenContent } from "./TokenContent" +import { CoreId, ICoreId } from "./types/CoreId" + +export interface ITokenContentRelationshipTemplate extends ITokenContent { + templateId: ICoreId + secretKey: ICryptoSecretKey +} + +@schema("https://schema.corp", "TokenContentRelationshipTemplate") +export class TokenContentRelationshipTemplate extends TokenContent implements ITokenContentRelationshipTemplate { + @validate() + @serialize() + public templateId: CoreId + + @validate() + @serialize() + public secretKey: CryptoSecretKey + + public static async from(value: ITokenContentRelationshipTemplate): Promise { + return await super.fromT(value, TokenContentRelationshipTemplate) + } + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentRelationshipTemplate) + } +} diff --git a/test/data/core/TokenContentString.ts b/test/data/core/TokenContentString.ts new file mode 100644 index 0000000..f157b21 --- /dev/null +++ b/test/data/core/TokenContentString.ts @@ -0,0 +1,21 @@ +import { schema, serialize, validate } from "@js-soft/ts-serval" +import { ITokenContent, TokenContent } from "./TokenContent" + +export interface ITokenContentString extends ITokenContent { + content: string +} + +@schema("https://schema.corp", "TokenContentString") +export class TokenContentString extends TokenContent { + @validate() + @serialize({ enforceString: true }) + public content: string + + public static async from(value: ITokenContentString): Promise { + return await super.fromT(value, TokenContentString) + } + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentString) + } +} diff --git a/test/data/core/types/CoreAddress.ts b/test/data/core/types/CoreAddress.ts new file mode 100644 index 0000000..64c8200 --- /dev/null +++ b/test/data/core/types/CoreAddress.ts @@ -0,0 +1,44 @@ +import { schema, serialize, serializeOnly, validate } from "@js-soft/ts-serval" +import { CoreSerializable, ICoreSerializable } from "../CoreSerializable" + +export interface ICoreAddress extends ICoreSerializable { + address: string +} + +/** + * A CoreAddress is the primary technical identitier of an account. + */ +@schema("https://schema.corp", "CoreAddress") +@serializeOnly("address", "string") +export class CoreAddress extends CoreSerializable { + @validate() + @serialize() + public address: string + + public static from(value: ICoreAddress | string): CoreAddress { + if (typeof value === "string") { + return super.from({ address: value }, CoreAddress) as CoreAddress + } + return super.from(value, CoreAddress) as CoreAddress + } + + public static deserialize(value: string): CoreAddress { + try { + return super.deserializeT(value, CoreAddress) + } catch (e) { + return this.from(value) + } + } + + public equals(address: CoreAddress): boolean { + return this.address === address.toString() + } + + public toString(): string { + return this.address + } + + public serialize(): string { + return this.address + } +} diff --git a/test/data/core/types/CoreDate.ts b/test/data/core/types/CoreDate.ts new file mode 100644 index 0000000..7309329 --- /dev/null +++ b/test/data/core/types/CoreDate.ts @@ -0,0 +1,62 @@ +import { serialize, serializeOnly, validate } from "@js-soft/ts-serval" +import { CoreSerializable, ICoreSerializable } from "../CoreSerializable" + +export interface ICoreDate extends ICoreSerializable { + date: string +} + +@serializeOnly("date", "string") +export class CoreDate extends CoreSerializable implements ICoreDate { + private readonly _dateTime: Date + public get dateTime(): Date { + return this._dateTime + } + + @validate() + @serialize() + public readonly date: string + + public constructor(dateTime: Date = new Date()) { + super() + this._dateTime = dateTime + this.date = this._dateTime.toISOString() + } + + /** + * Creates an ISO String. + */ + public toString(): string { + return this.dateTime.toISOString() + } + + public toISOString(): string { + return this.dateTime.toISOString() + } + + public serialize(): string { + return this.dateTime.toISOString() + } + + public static from(value: ICoreDate | string | number): CoreDate { + if (typeof value === "object") { + if (typeof value.date === "undefined") { + if (typeof (value as any).toISOString === "function") { + const iso = (value as any).toISOString() + return new CoreDate(new Date(iso)) + } + } else { + return new CoreDate(new Date(value.date)) + } + } + + if (typeof value === "number") { + return new CoreDate(new Date(value)) + } + + return new CoreDate(new Date(value as string)) + } + + public static deserialize(isoString: string): CoreDate { + return this.from(isoString) + } +} diff --git a/test/data/core/types/CoreId.ts b/test/data/core/types/CoreId.ts new file mode 100644 index 0000000..7785676 --- /dev/null +++ b/test/data/core/types/CoreId.ts @@ -0,0 +1,39 @@ +import { serialize, serializeOnly, validate } from "@js-soft/ts-serval" +import { CoreSerializable, ICoreSerializable } from "../CoreSerializable" + +export interface ICoreId extends ICoreSerializable { + id: string +} + +/** + * A CoreId is any kind of identifier we have in the system. + */ +@serializeOnly("id", "string") +export class CoreId extends CoreSerializable implements ICoreId { + @validate() + @serialize() + public id: string + + public toString(): string { + return this.id + } + + public equals(id: CoreId): boolean { + return this.id === id.toString() + } + + public static from(value: ICoreId | string): CoreId { + if (typeof value === "string" || value instanceof String) { + return super.fromT({ id: value }, CoreId) + } + return super.fromT(value, CoreId) + } + + public static deserialize(value: string): CoreId { + return this.from(value) + } + + public serialize(): string { + return this.id + } +} diff --git a/test/data/crypto/CoreBuffer.ts b/test/data/crypto/CoreBuffer.ts new file mode 100644 index 0000000..63cd31a --- /dev/null +++ b/test/data/crypto/CoreBuffer.ts @@ -0,0 +1,51 @@ +import { ISerializable, schema, Serializable } from "@js-soft/ts-serval" +import { Buffer } from "buffer" + +export interface ICoreBuffer extends ISerializable { + readonly buffer: Uint8Array + readonly length: number +} + +@schema("https://schema.corp", "CoreBuffer") +export class CoreBuffer extends Serializable implements ICoreBuffer { + private readonly _buffer: Uint8Array + + public constructor(value: any = []) { + super() + if (value instanceof ArrayBuffer) { + this._buffer = new Uint8Array(value, 0, value.byteLength) + } else if (value instanceof Uint8Array) { + this._buffer = value + } else if (value instanceof Array) { + this._buffer = Uint8Array.from(value) + } else if (value instanceof CoreBuffer) { + this._buffer = value.buffer + } else if (typeof value === "string") { + this._buffer = Buffer.from(value, "base64") + } + } + + public get buffer(): Uint8Array { + return this._buffer + } + + public get length(): number { + return this._buffer.length + } + + public toJSON(): Object { + return this.serialize() + } + + public serialize(): string { + return Buffer.from(this._buffer).toString("base64") + } + + public static deserialize(value: string): CoreBuffer { + return CoreBuffer.from(value) + } + + public static from(value: any): CoreBuffer { + return new CoreBuffer(value) + } +} diff --git a/test/data/crypto/CryptoCipher.ts b/test/data/crypto/CryptoCipher.ts new file mode 100644 index 0000000..2c03df6 --- /dev/null +++ b/test/data/crypto/CryptoCipher.ts @@ -0,0 +1,76 @@ +import { ISerializable, ISerialized, schema } from "@js-soft/ts-serval" +import { CoreBuffer, ICoreBuffer } from "./CoreBuffer" +import { CryptoEncryptionAlgorithm } from "./CryptoSecretKey" +import { CryptoSerializableAsync } from "./CryptoSerializableAsync" + +export interface ICryptoCipherSerialized extends ISerialized { + alg: number + cph: string + cnt?: number + nnc?: string +} + +export interface ICryptoCipher extends ISerializable { + algorithm: CryptoEncryptionAlgorithm + cipher: ICoreBuffer + counter?: number + nonce?: ICoreBuffer +} + +@schema("https://schema.corp", "CryptoCipher") +export class CryptoCipher extends CryptoSerializableAsync implements ICryptoCipher { + public static MIN_CIPHER_BYTES = 2 + public static MAX_CIPHER_BYTES: number = 100 * 1024 * 1024 + + public readonly algorithm: CryptoEncryptionAlgorithm + public readonly cipher: CoreBuffer + public readonly counter?: number + public readonly nonce?: CoreBuffer + + public toJSON(verbose = true): ICryptoCipherSerialized { + const obj: ICryptoCipherSerialized = { + cph: this.cipher.serialize(), + alg: this.algorithm + } + if (this.nonce) { + obj.nnc = this.nonce.serialize() + } + if (typeof this.counter !== "undefined") { + obj.cnt = this.counter + } + if (verbose) { + obj["@type"] = "CryptoCipher" + obj["@context"] = "https://schema.corp" + } + return obj + } + + public static async from(value: CryptoCipher | ICryptoCipher): Promise { + return await super.fromT(value, CryptoCipher) + } + + public static async fromJSON(value: ICryptoCipherSerialized): Promise { + let nonceBuffer: CoreBuffer | undefined = undefined + let counter: number | undefined = undefined + if (typeof value.nnc !== "undefined") { + nonceBuffer = CoreBuffer.deserialize(value.nnc) + } + + if (typeof value.cnt !== "undefined") { + counter = value.cnt + } + + const cipherBuffer = CoreBuffer.deserialize(value.cph) + return await this.from({ + algorithm: value.alg, + cipher: cipherBuffer, + nonce: nonceBuffer, + counter: counter + }) + } + + public static async deserialize(value: string): Promise { + const obj = JSON.parse(value) + return await this.fromJSON(obj) + } +} diff --git a/test/data/crypto/CryptoSecretKey.ts b/test/data/crypto/CryptoSecretKey.ts new file mode 100644 index 0000000..5b2f0fa --- /dev/null +++ b/test/data/crypto/CryptoSecretKey.ts @@ -0,0 +1,67 @@ +import { ISerializable, ISerialized, schema } from "@js-soft/ts-serval" +import { CoreBuffer, ICoreBuffer } from "./CoreBuffer" +import { CryptoSerializableAsync } from "./CryptoSerializableAsync" + +export interface ICryptoSecretKeySerialized extends ISerialized { + alg: number + key: string +} + +export interface ICryptoSecretKey extends ISerializable { + algorithm: CryptoEncryptionAlgorithm + secretKey: ICoreBuffer +} + +export const enum CryptoEncryptionAlgorithm { + /** + * AES 128-bit encryption with Galois-Counter-Mode + * 12-byte Initialization Vector is prepended to cipher + * 16-byte Authentication Tag is appended to cipher + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + AES128_GCM = 1, + /** + * AES 256-bit encryption with Galois-Counter-Mode + * 12-byte Initialization Vector is prepended to cipher + * 16-byte Authentication Tag is appended to cipher + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + AES256_GCM = 2, + // eslint-disable-next-line @typescript-eslint/naming-convention + XCHACHA20_POLY1305 = 3 +} + +@schema("https://schema.corp", "CryptoSecretKey") +export class CryptoSecretKey extends CryptoSerializableAsync implements ICryptoSecretKey { + public readonly secretKey: CoreBuffer + public readonly algorithm: CryptoEncryptionAlgorithm + + public toJSON(verbose = true): ICryptoSecretKeySerialized { + const obj: ICryptoSecretKeySerialized = { + key: this.secretKey.serialize(), + alg: this.algorithm + } + if (verbose) { + obj["@type"] = "CryptoSecretKey" + obj["@context"] = "https://schema.corp" + } + return obj + } + + public static async from(value: CryptoSecretKey | ICryptoSecretKey): Promise { + return await super.fromT(value, CryptoSecretKey) + } + + public static async fromJSON(value: ICryptoSecretKeySerialized): Promise { + const buffer = CoreBuffer.deserialize(value.key) + return await this.from({ + algorithm: value.alg as CryptoEncryptionAlgorithm, + secretKey: buffer + }) + } + + public static async deserialize(value: string): Promise { + const obj = JSON.parse(value) + return await this.fromJSON(obj) + } +} diff --git a/test/data/crypto/CryptoSerializableAsync.ts b/test/data/crypto/CryptoSerializableAsync.ts new file mode 100644 index 0000000..6f60fce --- /dev/null +++ b/test/data/crypto/CryptoSerializableAsync.ts @@ -0,0 +1,8 @@ +import { ISerializableAsync, schema, SerializableAsync } from "@js-soft/ts-serval" + +@schema("https://schema.corp", "CryptoSerializableAsync") +export class CryptoSerializableAsync extends SerializableAsync implements ISerializableAsync { + public serialize(verbose = true): string { + return JSON.stringify(this.toJSON(verbose)) + } +} diff --git a/test/data/crypto/CryptoSignature.ts b/test/data/crypto/CryptoSignature.ts new file mode 100644 index 0000000..4b48126 --- /dev/null +++ b/test/data/crypto/CryptoSignature.ts @@ -0,0 +1,93 @@ +import { ISerializableAsync, ISerialized, schema, serialize, validate } from "@js-soft/ts-serval" +import { CoreBuffer } from "./CoreBuffer" +import { CryptoSerializableAsync } from "./CryptoSerializableAsync" + +export interface ICryptoSignatureSerialized extends ISerialized { + sig: string + alg: number + kid?: string + id?: string +} + +export interface ICryptoSignature extends ISerializableAsync { + signature: CoreBuffer + algorithm: CryptoHashAlgorithm + keyId?: string + id?: string +} + +export const enum CryptoHashAlgorithm { + /** SHA256 Hash Algorithm with a hash of 32 bytes */ + SHA256 = 1, + /** SHA512 Hash Algorithm with a hash of 64 bytes */ + SHA512 = 2, + + BLAKE2B = 3 +} + +@schema("https://schema.corp", "CryptoSignature") +export class CryptoSignature extends CryptoSerializableAsync implements ICryptoSignature { + @serialize() + @validate() + public readonly signature: CoreBuffer + + @serialize() + @validate() + public readonly algorithm: CryptoHashAlgorithm + + @serialize() + @validate({ nullable: true }) + public readonly keyId?: string + + @serialize() + @validate({ nullable: true }) + public readonly id?: string + + public static checkHashAlgorithm(algorithm: number, throwError = true): Error | undefined { + let error: Error | undefined + switch (algorithm) { + case CryptoHashAlgorithm.BLAKE2B: + case CryptoHashAlgorithm.SHA256: + case CryptoHashAlgorithm.SHA512: + break + default: + error = new Error("Hash algorithm is not supported.") + break + } + + if (error && throwError) throw error + return error + } + + public toJSON(verbose = true): ICryptoSignatureSerialized { + const obj: ICryptoSignatureSerialized = { + sig: this.signature.serialize(), + alg: this.algorithm + } + if (verbose) { + obj["@type"] = "CryptoSignature" + obj["@context"] = "https://schema.corp" + } + return obj + } + + public static async from(value: CryptoSignature | ICryptoSignature): Promise { + return await super.fromT(value, CryptoSignature) + } + + public static async fromJSON(value: ICryptoSignatureSerialized): Promise { + const error = CryptoSignature.checkHashAlgorithm(value.alg) + if (error) throw error + + const buffer = CoreBuffer.from(value.sig) + return await this.from({ + signature: buffer, + algorithm: value.alg + }) + } + + public static async deserialize(value: string): Promise { + const obj = JSON.parse(value) + return await this.fromJSON(obj) + } +} diff --git a/test/index.ts b/test/index.ts new file mode 100644 index 0000000..8f33beb --- /dev/null +++ b/test/index.ts @@ -0,0 +1,74 @@ +import { ArrayInheritanceAsyncTest } from "./serialize/async/ArrayInheritanceAsync.test" +import { InheritanceAsyncTest } from "./serialize/async/InheritanceAsync.test" +import { SerializeAsyncAnyPropertyTest } from "./serialize/async/SerializeAsyncAnyProperty.test" +import { SerializeAsyncClassPropertyTest } from "./serialize/async/SerializeAsyncClassProperty.test" +import { SerializeAsyncEnforceStringPropertyTest } from "./serialize/async/SerializeAsyncEnforceStringProperty.test" +import { SerializeAsyncGenericPropertyTest } from "./serialize/async/SerializeAsyncGenericProperty.test" +import { SerializeAsyncMultiTypeTest } from "./serialize/async/SerializeAsyncMultiType.test" +import { SerializeAsyncTypedArrayTest } from "./serialize/async/SerializeAsyncTypedArray.test" +import { SerializeAsyncWrapperTest } from "./serialize/async/SerializeAsyncWrapper.test" +import { SerializeOnlyAsyncTest } from "./serialize/async/SerializeOnlyAsync.test" +import { ArrayInheritanceTest } from "./serialize/sync/ArrayInheritance.test" +import { InheritanceTest } from "./serialize/sync/Inheritance.test" +import { SerializeAnyPropertyTest } from "./serialize/sync/SerializeAnyProperty.test" +import { SerializeClassPropertyTest } from "./serialize/sync/SerializeClassProperty.test" +import { SerializeEnforceStringPropertyTest } from "./serialize/sync/SerializeEnforceStringProperty.test" +import { SerializeGenericPropertyTest } from "./serialize/sync/SerializeGenericProperty.test" +import { SerializeMultiTypeTest } from "./serialize/sync/SerializeMultiType.test" +import { SerializeOnlyTest } from "./serialize/sync/SerializeOnly.test" +import { SerializeTypedArrayTest } from "./serialize/sync/SerializeTypedArray.test" +import { SerializeWrapperTest } from "./serialize/sync/SerializeWrapper.test" +import { CoreTest } from "./usage/Core.test" +import { ValidateAnyPropertyTest } from "./validate/ValidateAnyProperty.test" +import { ValidateGenericPropertyTest } from "./validate/ValidateGenericProperty.test" +import { ValidatePropertyAnnotatedWithTypeTest } from "./validate/ValidatePropertyAnnotatedWithTypeTest.test" + +export class ServalTest { + public static runSerializeAsync(): void { + SerializeAsyncEnforceStringPropertyTest.init() + SerializeAsyncClassPropertyTest.init() + SerializeAsyncMultiTypeTest.init() + SerializeOnlyAsyncTest.init() + SerializeAsyncGenericPropertyTest.init() + SerializeAsyncAnyPropertyTest.init() + InheritanceAsyncTest.init() + ArrayInheritanceAsyncTest.init() + SerializeAsyncTypedArrayTest.init() + SerializeAsyncWrapperTest.init() + } + + public static runSerializeSync(): void { + ValidatePropertyAnnotatedWithTypeTest.init() + SerializeEnforceStringPropertyTest.init() + SerializeClassPropertyTest.init() + SerializeMultiTypeTest.init() + SerializeOnlyTest.init() + InheritanceTest.init() + SerializeGenericPropertyTest.init() + SerializeAnyPropertyTest.init() + ArrayInheritanceTest.init() + SerializeTypedArrayTest.init() + SerializeWrapperTest.init() + } + + public static runValidate(): void { + ValidateAnyPropertyTest.init() + ValidateGenericPropertyTest.init() + } + + public static runUsage(): void { + CoreTest.init() + } + + public static run(): void { + this.runSerializeAsync() + this.runSerializeSync() + this.runValidate() + this.runUsage() + } + + public static init(): void { + this.run() + } +} +ServalTest.init() diff --git a/test/performance.ts b/test/performance.ts new file mode 100644 index 0000000..1e17fc9 --- /dev/null +++ b/test/performance.ts @@ -0,0 +1,122 @@ +/* eslint-disable no-console */ +import { schema, Serializable, serialize, validate } from "@js-soft/ts-serval" + +class OldCheckEmployee { + private _name: string + + public constructor(name: string) { + this.name = name + } + public set name(value: string) { + if (typeof value === "undefined") { + throw new Error("Value is not defined") + } + + if (typeof value !== "string") { + throw new Error("Value is not a string") + } + + if (value.length < 2) { + throw new Error("Value is shorter than 2 characters") + } + + if (value.length > 10) { + throw new Error("Value is longer than 10 characters") + } + + const regExp = new RegExp("^[\\w]+$") + if (!regExp.test(value)) { + throw new Error("Value contains other characters than the allowed ones.") + } + this._name = value + } + + public get name(): string { + return this._name + } +} + +interface IRole { + role: string +} + +@schema("http://schema.org", "Role") +class Role extends Serializable implements IRole { + @serialize() + public role: string + + public static from(value: IRole): Role { + return super.fromT(value, Role) + } +} + +@schema("http://schema.org", "Person") +class NewCheckEmployee extends Serializable { + @validate({ min: 2, max: 10, allowedChars: "\\w" }) + @serialize() + public name: string + + @serialize() + public role: Role + + public checkRole(): string | undefined { + return "Nope" + } + + public static from(value: Object): NewCheckEmployee { + return super.fromT(value, NewCheckEmployee) + } +} + +function measure(functionToMeasure: Function, thisArg?: any, argArray?: []): number { + const start = new Date().getTime() + functionToMeasure.apply(thisArg, argArray) + const duration = new Date().getTime() - start + return duration +} + +const iterations = 1 + +const oldEmployees: OldCheckEmployee[] = [] +const oldCreation = measure(() => { + for (let i = 0; i < iterations; i++) { + oldEmployees.push(new OldCheckEmployee("ba")) + } +}) +console.log(`Time to create old employees: ${oldCreation}ms`) + +const newEmployees: NewCheckEmployee[] = [] +const newCreation = measure(() => { + for (let i = 0; i < iterations; i++) { + const a = new NewCheckEmployee() + a.name = "aaa" + newEmployees.push(a) + } +}) +console.log(`Time to create new employees: ${newCreation}ms`) + +const oldCheck = measure(() => { + for (let i = 0; i < iterations; i++) { + const emp = oldEmployees[i] + emp.name = "anEmployeeName" + } +}) +console.log(`Time to check old employees: ${oldCheck}ms`) + +let employee: NewCheckEmployee +const newCheck = measure(() => { + for (let i = 0; i < iterations; i++) { + employee = newEmployees[i] + employee.name = "anEmployeeName" + } +}) +console.log(`Time to check new employees: ${newCheck}ms`) + +const e: NewCheckEmployee = new NewCheckEmployee() +e.name = "Hossa" +e.role = Role.from({ role: "aRole" }) + +let serialized = e.serialize() +const parsed = JSON.parse(serialized) +const loaded: NewCheckEmployee = NewCheckEmployee.from(parsed) as any +serialized = loaded.serialize() diff --git a/test/serialize/async/ArrayInheritanceAsync.test.ts b/test/serialize/async/ArrayInheritanceAsync.test.ts new file mode 100644 index 0000000..b7191bf --- /dev/null +++ b/test/serialize/async/ArrayInheritanceAsync.test.ts @@ -0,0 +1,192 @@ +import { schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +/** + * + * SerializableAsync + * |- RelationshipTemplateArrayAsync + * |- TokenContentArrayAsync + * | |- TokenGenericAsync + * | |- TokenContentRelationshipTemplateArrayAsync + * | |- TokenContentStringArrayAsync + */ + +@schema("https://schema.local.corp", "RelationshipTemplateArrayAsync") +class RelationshipTemplateArrayAsync extends SerializableAsync { + @serialize() + public template: Object + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, RelationshipTemplateArrayAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, RelationshipTemplateArrayAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentArrayAsync") +class TokenContentArrayAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public title: string + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentArrayAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentArrayAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentRelationshipTemplateArrayAsync") +class TokenContentRelationshipTemplateArrayAsync extends TokenContentArrayAsync { + @serialize() + public content: RelationshipTemplateArrayAsync + + @serialize({ optional: true }) + public optionalContent: string + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentRelationshipTemplateArrayAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentRelationshipTemplateArrayAsync) + } +} + +@schema("https://schema.local.corp", "TokenRelationshipTemplateArrayAsync") +class TokenRelationshipTemplateArrayAsync extends SerializableAsync { + @serialize({ deserializeStrings: true, type: TokenContentRelationshipTemplateArrayAsync }) + public templates: TokenContentRelationshipTemplateArrayAsync[] + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenRelationshipTemplateArrayAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenRelationshipTemplateArrayAsync) + } +} + +export class ArrayInheritanceAsyncTest { + public static init(): void { + function expectValidToken(token) { + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenRelationshipTemplateArrayAsync) + expect(token.templates).to.exist + expect(token.templates).to.be.instanceOf(Array) + expect(token.templates.length).to.equal(2) + + const item0 = token.templates[0] + expect(item0).to.be.instanceOf(SerializableAsync) + expect(item0).to.be.instanceOf(TokenContentArrayAsync) + expect(item0).to.be.instanceOf(TokenContentRelationshipTemplateArrayAsync) + expect(item0.optionalContent).not.to.exist + expect(item0.title).to.exist + expect(item0.title).to.equal("Test") + expect(item0.notToBeSerialized).to.exist + expect(item0.notToBeSerialized).to.equal("avalue") + expect(item0.content.template).to.exist + expect(item0.content.template.myprop).to.exist + + const item1 = token.templates[1] + expect(item1).to.be.instanceOf(SerializableAsync) + expect(item1).to.be.instanceOf(TokenContentArrayAsync) + expect(item1).to.be.instanceOf(TokenContentRelationshipTemplateArrayAsync) + expect(item1.optionalContent).to.exist + expect(item1.optionalContent).to.equal("someOptionalContent") + expect(item1.title).to.exist + expect(item1.title).to.equal("Test 2") + expect(item1.notToBeSerialized).to.exist + expect(item1.notToBeSerialized).to.equal("avalue") + expect(item1.content.template).to.exist + expect(item1.content.template.myprop).to.exist + } + describe("ArrayInheritanceAsync", function () { + describe("TokenRelationshipTemplateArrayAsync", function () { + it("from() creates instance from given interface (all objects)", async function () { + const token: any = await TokenRelationshipTemplateArrayAsync.from({ + templates: [ + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }) + }), + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test 2", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + expectValidToken(token) + }) + + it("should toJSON() correctly", async function () { + const token: any = await TokenRelationshipTemplateArrayAsync.from({ + templates: [ + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }) + }), + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test 2", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + const serialized = JSON.stringify(token.toJSON()) + const serializedAvailable = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArrayAsync","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + expect(serialized).to.equal(serializedAvailable) + }) + + it("should serialize correctly", async function () { + const token: any = await TokenRelationshipTemplateArrayAsync.from({ + templates: [ + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }) + }), + await TokenContentRelationshipTemplateArrayAsync.from({ + title: "Test 2", + content: await RelationshipTemplateArrayAsync.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + const serialized = token.serialize() + const serializedAvailable = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArrayAsync","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + expect(serialized).to.equal(serializedAvailable) + }) + + it("should be deserialized correctly", async function () { + const serialized = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArrayAsync","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + const token = await SerializableAsync.deserializeUnknown(serialized) + expectValidToken(token) + }) + }) + }) + } +} diff --git a/test/serialize/async/InheritanceAsync.test.ts b/test/serialize/async/InheritanceAsync.test.ts new file mode 100644 index 0000000..3e1b8dc --- /dev/null +++ b/test/serialize/async/InheritanceAsync.test.ts @@ -0,0 +1,719 @@ +import { schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +/** + * + * SerializableAsync + * |- RelationshipTemplateAsync + * |- TokenContentAsync + * | |- TokenGenericAsync + * | |- TokenContentRelationshipTemplateAsync + * | |- TokenContentStringAsync + */ + +@schema("https://schema.local.corp", "RelationshipTemplateAsync") +class RelationshipTemplateAsync extends SerializableAsync { + @serialize({ deserializeStrings: true }) + public template: Object + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, RelationshipTemplateAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, RelationshipTemplateAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentAsync") +class TokenContentAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public title: string + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentGenericAsync") +class TokenContentGenericAsync extends TokenContentAsync { + @serialize({ any: true, deserializeStrings: true }) + public content: any + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentGenericAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentGenericAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentRelationshipTemplateAsync") +class TokenContentRelationshipTemplateAsync extends TokenContentAsync { + @serialize({ deserializeStrings: true }) + public content: RelationshipTemplateAsync + + @serialize({ optional: true }) + public optionalContent: string + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentRelationshipTemplateAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentRelationshipTemplateAsync) + } +} + +@schema("https://schema.local.corp", "TokenContentStringAsync") +class TokenContentStringAsync extends TokenContentAsync { + @serialize() + public content: String + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenContentStringAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenContentStringAsync) + } +} + +@schema("https://schema.local.corp", "TokenRelationshipTemplatesAsync") +class TokenRelationshipTemplatesAsync extends SerializableAsync { + @serialize({ type: TokenContentRelationshipTemplateAsync }) + public templates: TokenContentRelationshipTemplateAsync[] + + public static async deserialize(value: string): Promise { + return await super.deserializeT(value, TokenRelationshipTemplatesAsync) + } + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenRelationshipTemplatesAsync) + } +} + +export class InheritanceAsyncTest { + public static init(): void { + describe("InheritanceAsync", function () { + describe("TokenContentString", function () { + it("from() creates instance from given interface", async function () { + const token: any = await TokenContentStringAsync.from({ + title: "Test", + content: "someContent" + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given instance", async function () { + const useToken: any = await TokenContentStringAsync.from({ + title: "Test", + content: "someContent" + }) + const token: any = await TokenContentStringAsync.from(useToken) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given object", async function () { + const useToken: any = await TokenContentStringAsync.from({ + title: "Test", + content: "someContent" + }) + const object: Object = useToken.toJSON() + const token: any = await TokenContentStringAsync.from(object) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("deserialize() creates instance from given string", async function () { + const token: any = await TokenContentStringAsync.deserialize( + '{"content":"someContent","title":"Test"}' + ) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("serialize() creates string from given instance", async function () { + const token: any = await TokenContentStringAsync.deserialize( + '{"title":"Test","content":"someContent"}' + ) + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentStringAsync","content":"someContent","title":"Test"}' + ) + }) + + it("multiple de/serialization works", async function () { + let token: any = await TokenContentStringAsync.deserialize( + '{"title":"Test","content":"someContent"}' + ) + let string: string = token.serialize() + token = await TokenContentStringAsync.deserialize(string) + string = token.serialize() + token = await TokenContentStringAsync.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentStringAsync","content":"someContent","title":"Test"}' + ) + }) + }) + + describe("TokenRelationshipTemplatesAsync", function () { + it("from() creates instance from given interface (all objects)", async function () { + const token: any = await TokenRelationshipTemplatesAsync.from({ + templates: [ + await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: await RelationshipTemplateAsync.from({ + template: { myprop: "myvalue" } + }) + }), + await TokenContentRelationshipTemplateAsync.from({ + title: "Test 2", + content: await RelationshipTemplateAsync.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenRelationshipTemplatesAsync) + expect(token.templates).to.exist + expect(token.templates).to.be.instanceOf(Array) + expect(token.templates.length).to.equal(2) + + const item0 = token.templates[0] + expect(item0).to.be.instanceOf(SerializableAsync) + expect(item0).to.be.instanceOf(TokenContentAsync) + expect(item0).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(item0.optionalContent).not.to.exist + expect(item0.title).to.exist + expect(item0.title).to.equal("Test") + expect(item0.notToBeSerialized).to.exist + expect(item0.notToBeSerialized).to.equal("avalue") + expect(item0.content.template).to.exist + expect(item0.content.template.myprop).to.exist + + const item1 = token.templates[1] + expect(item1).to.be.instanceOf(SerializableAsync) + expect(item1).to.be.instanceOf(TokenContentAsync) + expect(item1).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(item1.optionalContent).to.exist + expect(item1.optionalContent).to.equal("someOptionalContent") + expect(item1.title).to.exist + expect(item1.title).to.equal("Test 2") + expect(item1.notToBeSerialized).to.exist + expect(item1.notToBeSerialized).to.equal("avalue") + expect(item1.content.template).to.exist + expect(item1.content.template.myprop).to.exist + }) + }) + + describe("TokenContentRelationshipTemplateAsync", function () { + it("from() creates instance from given interface (all objects)", async function () { + const token: any = await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: await RelationshipTemplateAsync.from({ + template: { myprop: "myvalue" } + }) + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.optionalContent).not.to.exist + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + }) + + it("from() creates instance from given interface (all objects, optional content)", async function () { + const token: any = await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: await RelationshipTemplateAsync.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "Testing" + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.optionalContent).to.exist + expect(token.optionalContent).to.equal("Testing") + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + }) + + it("from() creates instance from given interface (with strings to deserialize)", async function () { + const token: any = await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("from() creates instance from given instance", async function () { + const useToken: any = await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + const token: any = await TokenContentRelationshipTemplateAsync.from(useToken) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("from() creates instance from given object", async function () { + const useToken: any = await TokenContentRelationshipTemplateAsync.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + const object: any = useToken.toJSON() + expect(object["@type"]).to.equal("TokenContentRelationshipTemplateAsync") + expect(object["@context"]).to.equal("https://schema.local.corp") + expect(object.title).to.exist + expect(object.content).to.exist + expect(object.optionalContent).to.not.exist + expect(object.content.template).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + const token: any = await TokenContentRelationshipTemplateAsync.from(object) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("deserialize() creates instance from given string", async function () { + const str = '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + const token: any = await TokenContentRelationshipTemplateAsync.deserialize(str) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token).not.to.be.instanceOf(TokenContentGenericAsync) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplateAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("serialize() creates string from given instance", async function () { + const token: any = await TokenContentStringAsync.deserialize( + '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + ) + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentStringAsync","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}","title":"Test"}' + ) + }) + + it("multiple de/serialization works", async function () { + let token: any = await TokenContentStringAsync.deserialize( + '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + ) + let string: string = token.serialize() + token = await TokenContentStringAsync.deserialize(string) + string = token.serialize() + token = await TokenContentStringAsync.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentStringAsync","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}","title":"Test"}' + ) + }) + }) + + describe("TokenContentGenericAsync", function () { + it("from() creates instance from given interface", async function () { + const token: any = await TokenContentGenericAsync.from({ + title: "Test", + content: "someContent" + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given interface (1)", async function () { + const token: any = await TokenContentGenericAsync.from({ + title: "Test", + content: true + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given interface (2)", async function () { + const token: any = await TokenContentGenericAsync.from({ + title: "Test", + content: 5 + }) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("from() creates instance from given instance (1)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: "someContent" + }) + + const token: any = await TokenContentGenericAsync.from(useToken) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given instance (2)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: true + }) + + const token: any = await TokenContentGenericAsync.from(useToken) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given instance (3)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: 5 + }) + + const token: any = await TokenContentGenericAsync.from(useToken) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("from() creates instance from given object (1)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: "someContent" + }) + + const object: Object = useToken.toJSON() + + const token: any = await TokenContentGenericAsync.from(object) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given object (2)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: true + }) + + const object: Object = useToken.toJSON() + + const token: any = await TokenContentGenericAsync.from(object) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given object (3)", async function () { + const useToken: any = await TokenContentGenericAsync.from({ + title: "Test", + content: 5 + }) + + const object: Object = useToken.toJSON() + + const token: any = await TokenContentGenericAsync.from(object) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("deserialize() creates instance from given string", async function () { + const token: any = await TokenContentGenericAsync.deserialize( + '{"title":"Test","content":"someContent"}' + ) + + expect(token).to.be.instanceOf(SerializableAsync) + expect(token).to.be.instanceOf(TokenContentAsync) + expect(token).to.be.instanceOf(TokenContentGenericAsync) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplateAsync) + expect(token).not.to.be.instanceOf(TokenContentStringAsync) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("serialize() creates string from given instance (1)", async function () { + const token: any = await TokenContentGenericAsync.deserialize( + '{"title":"Test","content":"someContent"}' + ) + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":"someContent","title":"Test"}' + ) + }) + + it("serialize() creates string from given instance (2)", async function () { + const token: any = await TokenContentGenericAsync.deserialize('{"title":"Test","content":true}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":true,"title":"Test"}' + ) + }) + + it("serialize() creates string from given instance", async function () { + const token: any = await TokenContentGenericAsync.deserialize('{"title":"Test","content":5}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":5,"title":"Test"}' + ) + }) + + it("multiple de/serialization works", async function () { + let token: any = await TokenContentGenericAsync.deserialize( + '{"title":"Test","content":"someContent"}' + ) + let string: string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":"someContent","title":"Test"}' + ) + }) + + it("multiple de/serialization works (1)", async function () { + let token: any = await TokenContentGenericAsync.deserialize('{"title":"Test","content":true}') + let string: string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":true,"title":"Test"}' + ) + }) + + it("multiple de/serialization works (2)", async function () { + let token: any = await TokenContentGenericAsync.deserialize('{"title":"Test","content":5}') + let string: string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + token = await TokenContentGenericAsync.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGenericAsync","content":5,"title":"Test"}' + ) + }) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncAnyProperty.test.ts b/test/serialize/async/SerializeAsyncAnyProperty.test.ts new file mode 100644 index 0000000..bf37ed0 --- /dev/null +++ b/test/serialize/async/SerializeAsyncAnyProperty.test.ts @@ -0,0 +1,39 @@ +import { schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "TokenSerializableAsyncContentAny") +class TokenSerializableAsyncContentAny extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize({ any: true }) + public content: any + + public static async from(value: Object): Promise { + return (await super.from(value, TokenSerializableAsyncContentAny)) as TokenSerializableAsyncContentAny + } +} + +export class SerializeAsyncAnyPropertyTest { + public static init(): void { + describe("SerializeAsyncAnyProperty", function () { + describe("SerializableAsyncContent", function () { + it("should deserialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContentAny.from({ content: { myprop: "someValue" } }) + expect(token).instanceOf(TokenSerializableAsyncContentAny) + expect(token.content, "Content doesnt exist").to.exist + expect(token.content.myprop, "Property doesnt exist").to.exist + expect(token.content.myprop).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContentAny.from({ content: { myprop: "someValue" } }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.myprop, "Property doesnt exist").to.exist + expect(object.content.myprop).to.equal("someValue", "Property doesnt equal string") + }) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncClassProperty.test.ts b/test/serialize/async/SerializeAsyncClassProperty.test.ts new file mode 100644 index 0000000..2b58279 --- /dev/null +++ b/test/serialize/async/SerializeAsyncClassProperty.test.ts @@ -0,0 +1,329 @@ +import { schema, Serializable, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" +import { BetterAttribute } from "../../data/consumption/BetterAttribute" +import { CoreSerializable } from "../../data/core/CoreSerializable" +import { CoreId } from "../../data/core/types/CoreId" +import { expectThrowsAsync } from "../../testUtil" + +@schema("https://schema.local.corp", "TokenSerializeAttributeAsync") +class TokenSerializeAttributeAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: Attribute + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializeAttributeAsync) + } +} + +export class SerializeAsyncClassPropertyTest { + public static init(): void { + describe("SerializeAsyncClassProperty", function () { + let attr: any + let token: any + let object: any + + it("should parse correct arbitrary content", async function () { + token = await TokenSerializeAttributeAsync.from({ content: { name: "firstname", value: "aFirstname" } }) + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the arbitrary content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should serialize the arbitrary content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should parse correct instantiated content", async function () { + attr = Attribute.from({ name: "firstname", value: "aFirstname" }) + token = await TokenSerializeAttributeAsync.from({ content: attr }) + expect(token).to.exist + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the instantiated content", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should parse correct instantiated content (subclass)", async function () { + attr = BetterAttribute.from({ name: "firstname", value: "aFirstname" }) + token = await TokenSerializeAttributeAsync.from({ content: attr }) + expect(token).to.exist + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content).instanceOf(BetterAttribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the subclasses content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.exist + expect(object.content["@type"]).equals("BetterAttribute") + expect(object.content["@context"]).to.exist + }) + + it("should parse correct serialized content again (subclass)", async function () { + token = await TokenSerializeAttributeAsync.from(object) + expect(token).to.exist + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content).instanceOf(BetterAttribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the subclasses content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.exist + expect(object.content["@type"]).equals("BetterAttribute") + expect(object.content["@context"]).to.exist + }) + + it("should not parse additional arbitrary content", async function () { + token = await TokenSerializeAttributeAsync.from({ + content: { name: "firstname", value: "aFirstname", anotherProp: "anotherPropValue" }, + anotherProp: "anotherPropValue" + }) + expect(token).to.exist + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + expect(token.content.anotherProp).to.not.exist + expect(token.anotherProp).to.not.exist + }) + + it("should not serialize the additional arbitrary content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not serialize the additional arbitrary content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not parse additional instantiated content", async function () { + attr = Attribute.from({ name: "firstname", value: "aFirstname" }) + attr.anotherProp = "anotherPropValue" + token = await TokenSerializeAttributeAsync.from({ + content: attr, + anotherProp: "anotherPropValue" + }) + expect(token).to.exist + expect(token).instanceOf(SerializableAsync) + expect(token).instanceOf(TokenSerializeAttributeAsync) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + expect(token.anotherProp).to.not.exist + // This is intentional, if somebody sets an instance here, it is actually referenced + // and not copied, thus the arbritrary properties are copied too (for the object) + expect(token.content.anotherProp).to.exist + }) + + it("should not serialize the additional instantiated content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not serialize the additional instantiated content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not serialize non-known arbitrary content (verbose)", function () { + token.content.anotherProp = "test" + token.anotherProp = "test" + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttributeAsync") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not serialize non-known arbitrary content (non-verbose)", function () { + token.content.anotherProp = "test" + token.anotherProp = "test" + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(SerializableAsync) + expect(object).not.instanceOf(TokenSerializeAttributeAsync) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.anotherProp).to.not.exist + expect(object.anotherProp).to.not.exist + }) + + it("should not parse incorrect instantiated content", async function () { + const id = CoreId.from("Test") + await expectThrowsAsync( + async () => + await TokenSerializeAttributeAsync.from({ + content: id + }) + ) + + await expectThrowsAsync( + async () => + await TokenSerializeAttributeAsync.from({ + conten: id + }) + ) + }) + + it("should not parse incorrect arbitrary content", async function () { + await expectThrowsAsync( + async () => + await TokenSerializeAttributeAsync.from({ + content: { nam: "firstname", value: "aFirstname" } + }) + ) + + await expectThrowsAsync( + async () => + await TokenSerializeAttributeAsync.from({ + conten: { name: "firstname", value: "aFirstname" } + }) + ) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncEnforceStringProperty.test.ts b/test/serialize/async/SerializeAsyncEnforceStringProperty.test.ts new file mode 100644 index 0000000..53c779c --- /dev/null +++ b/test/serialize/async/SerializeAsyncEnforceStringProperty.test.ts @@ -0,0 +1,73 @@ +import { schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" + +@schema("https://schema.local.corp", "TokenSerializableAsyncEnforceString") +class TokenSerializableAsyncEnforceString extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize({ enforceString: true }) + public content: Attribute + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableAsyncEnforceString) + } +} + +export class SerializeAsyncEnforceStringPropertyTest { + public static init(): void { + describe("SerializeAsyncEnforceStringProperty", function () { + let token: TokenSerializableAsyncEnforceString + it("should create from object", async function () { + const attribute = Attribute.from({ name: "firstname", value: "test" }) + const serialized = attribute.serialize() + token = await TokenSerializableAsyncEnforceString.from({ content: serialized }) + expect(token).instanceOf(TokenSerializableAsyncEnforceString) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).is.a("string") + expect(token.content.value).equals("test") + }) + + it("should serialize as JSON", function () { + const tokenAsJSON = token.toJSON() as any + + expect(tokenAsJSON).to.be.a("object") + expect(tokenAsJSON).not.to.be.instanceOf(TokenSerializableAsyncEnforceString) + expect(tokenAsJSON).to.exist + expect(tokenAsJSON.content).to.be.a("string") + expect(tokenAsJSON.content).to.equal('{"name":"firstname","value":"test"}') + }) + + it("should deserialize from object (as string)", async function () { + token = await TokenSerializableAsyncEnforceString.from(token.toJSON()) + expect(token).instanceOf(TokenSerializableAsyncEnforceString) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).is.a("string") + expect(token.content.value).equals("test") + }) + + it("should serialize as string", function () { + const serialized = token.serialize() + + expect(serialized).to.be.a("string") + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableAsyncEnforceString","content":"{\\"name\\":\\"firstname\\",\\"value\\":\\"test\\"}"}' + ) + }) + + it("should deserialize from string", async function () { + const deserializedToken = await TokenSerializableAsyncEnforceString.deserializeT( + token.serialize(), + TokenSerializableAsyncEnforceString + ) + expect(deserializedToken).instanceOf(TokenSerializableAsyncEnforceString) + expect(deserializedToken.content).instanceOf(Attribute) + expect(deserializedToken.content.name).equals("firstname") + expect(deserializedToken.content.value).is.a("string") + expect(deserializedToken.content.value).equals("test") + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncGenericProperty.test.ts b/test/serialize/async/SerializeAsyncGenericProperty.test.ts new file mode 100644 index 0000000..5268521 --- /dev/null +++ b/test/serialize/async/SerializeAsyncGenericProperty.test.ts @@ -0,0 +1,80 @@ +import { JSONWrapper, JSONWrapperAsync, schema, Serializable, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "TokenSerializableAsyncContent") +class TokenSerializableAsyncContent extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: Serializable + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableAsyncContent) + } +} + +@schema("https://schema.local.corp", "TokenSerializableAsyncContentAsync") +class TokenSerializableAsyncContentAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: SerializableAsync + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableAsyncContentAsync) + } +} + +export class SerializeAsyncGenericPropertyTest { + public static init(): void { + describe("SerializeAsyncGenericProperty", function () { + describe("SerializableAsyncContent", function () { + it("should deserialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContent.from({ + content: { someProperty: "someValue" } + }) + expect(token).to.instanceOf(TokenSerializableAsyncContent) + expect(token.content).instanceOf(JSONWrapper) + expect(token.content.value, "Content doesnt exist").to.exist + expect(token.content.value.someProperty, "Property doesnt exist").to.exist + expect(token.content.value.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContent.from({ + content: { someProperty: "someValue" } + }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + }) + + describe("SerializableAsyncContentAsync", function () { + it("should deserialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContentAsync.from({ + content: { someProperty: "someValue" } + }) + expect(token).to.instanceOf(TokenSerializableAsyncContentAsync) + expect(token.content).instanceOf(JSONWrapperAsync) + expect(token.content.value, "Content doesnt exist").to.exist + expect(token.content.value.someProperty, "Property doesnt exist").to.exist + expect(token.content.value.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", async function () { + const token: any = await TokenSerializableAsyncContentAsync.from({ + content: { someProperty: "someValue" } + }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncMultiType.test.ts b/test/serialize/async/SerializeAsyncMultiType.test.ts new file mode 100644 index 0000000..1a5c3a4 --- /dev/null +++ b/test/serialize/async/SerializeAsyncMultiType.test.ts @@ -0,0 +1,214 @@ +import { PrimitiveType, schema, SerializableAsync, serialize, validate } from "@js-soft/ts-serval" +import { expect } from "chai" +import { expectThrowsAsync } from "../../testUtil" + +interface ITokenContentMultiAsync { + value: string | number | boolean +} + +@schema("https://schema.local.corp", "TokenContentMultiAsync") +class TokenContentMultiAsync extends SerializableAsync implements ITokenContentMultiAsync { + public notToBeSerialized = "avalue" + + @validate({ allowedTypes: [PrimitiveType.String, PrimitiveType.Number, PrimitiveType.Boolean] }) + @serialize() + public value: string | number | boolean + + public static async from(value: ITokenContentMultiAsync): Promise { + return await super.fromT(value, TokenContentMultiAsync) + } +} + +export class SerializeAsyncMultiTypeTest { + public static init(): void { + describe("SerializeMultiType", function () { + it("should serialize the given property as string", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: "string" }) + const object: any = token.toJSON() + expect(object.value).be.a("string") + expect(object.value).equals("string") + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + ) + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("string") + }) + + it("should serialize the given property as string (empty)", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: "" }) + const object: any = token.toJSON() + expect(object.value).be.a("string") + expect(object.value).equals("") + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + )! + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("string") + expect(object.value).equals("") + }) + + it("should serialize the given property as boolean (true)", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: true }) + const object: any = token.toJSON() + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + )! + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + }) + + it("should serialize the given property as boolean (false)", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: false }) + const object: any = token.toJSON() + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + )! + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + }) + + it("should serialize the given property as number", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: 55.5 }) + const object: any = token.toJSON() + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + )! + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + }) + + it("should serialize the given property as number (zero)", async function () { + const token: TokenContentMultiAsync = await TokenContentMultiAsync.from({ value: 0 }) + const object: any = token.toJSON() + expect(object.value).be.a("number") + expect(object.value).equals(0) + + const parsed: TokenContentMultiAsync = await TokenContentMultiAsync.from(object) + expect(parsed).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMultiAsync = await TokenContentMultiAsync.deserializeT( + serialized2, + TokenContentMultiAsync + )! + expect(parsed2).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized3 = parsed2.serialize() + const parsed3 = await SerializableAsync.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized4 = parsed3.toJSON() + const parsed4 = await SerializableAsync.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMultiAsync) + expect(object.value).be.a("number") + expect(object.value).equals(0) + }) + + it("should not deserialize property with invalid type", async function () { + const value: any = { value: ["a", "b"] } + await expectThrowsAsync( + async () => await TokenContentMultiAsync.from(value), + "TokenContentMultiAsync.value" + ) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncTypedArray.test.ts b/test/serialize/async/SerializeAsyncTypedArray.test.ts new file mode 100644 index 0000000..9746e92 --- /dev/null +++ b/test/serialize/async/SerializeAsyncTypedArray.test.ts @@ -0,0 +1,141 @@ +import { schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { expectThrowsAsync } from "../../testUtil" + +@schema("https://schema.local.corp", "TokenTypedArrayStringAsync") +class TokenTypedArrayStringAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize({ type: String }) + public content: string[] + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenTypedArrayStringAsync) + } +} + +@schema("https://schema.local.corp", "TokenTypedArrayNumberAsync") +class TokenTypedArrayNumberAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize({ type: Number }) + public content: number[] + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenTypedArrayNumberAsync) + } +} + +@schema("https://schema.local.corp", "TokenTypedArrayBooleanAsync") +class TokenTypedArrayBooleanAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize({ type: Boolean }) + public content: boolean[] + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenTypedArrayBooleanAsync) + } +} + +export class SerializeAsyncTypedArrayTest { + public static init(): void { + describe("SerializeAsyncTypedArray", function () { + describe("TokenTypedArrayStringAsync", function () { + let token: TokenTypedArrayStringAsync + it("should deserialize string arrays", async function () { + token = await TokenTypedArrayStringAsync.from({ content: ["Test1", "Test2", ""] }) + expect(token).to.be.instanceOf(TokenTypedArrayStringAsync) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals("Test1") + expect(token.content[1]).equals("Test2") + expect(token.content[2]).equals("") + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayStringAsync) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals("Test1") + expect(object.content[1]).equals("Test2") + expect(object.content[2]).equals("") + }) + + it("should not deserialize non-string arrays", async function () { + await expectThrowsAsync( + async () => await TokenTypedArrayStringAsync.from({ content: [true, "Test2", "Test3"] }) + ) + + await expectThrowsAsync( + async () => await TokenTypedArrayStringAsync.from({ content: [null, "Test2", "Test3"] }) + ) + }) + }) + + describe("TokenTypedArrayNumberAsync", function () { + let token: TokenTypedArrayNumberAsync + it("should deserialize number arrays", async function () { + token = await TokenTypedArrayNumberAsync.from({ content: [5, -1.5, 0] }) + expect(token).to.be.instanceOf(TokenTypedArrayNumberAsync) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals(5) + expect(token.content[1]).equals(-1.5) + expect(token.content[2]).equals(0) + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayNumberAsync) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals(5) + expect(object.content[1]).equals(-1.5) + expect(object.content[2]).equals(0) + }) + + it("should not deserialize non-number arrays", async function () { + await expectThrowsAsync( + async () => await TokenTypedArrayNumberAsync.from({ content: [true, -1.5, "Test3"] }) + ) + + await expectThrowsAsync( + async () => await TokenTypedArrayNumberAsync.from({ content: [null, -1.5, "Test3"] }) + ) + }) + }) + + describe("TokenTypedArrayBooleanAsync", function () { + let token: TokenTypedArrayBooleanAsync + it("should deserialize boolean arrays", async function () { + token = await TokenTypedArrayBooleanAsync.from({ content: [true, false, true] }) + expect(token).to.be.instanceOf(TokenTypedArrayBooleanAsync) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals(true) + expect(token.content[1]).equals(false) + expect(token.content[2]).equals(true) + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayBooleanAsync) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals(true) + expect(object.content[1]).equals(false) + expect(object.content[2]).equals(true) + }) + + it("should not deserialize non-boolean arrays", async function () { + await expectThrowsAsync( + async () => await TokenTypedArrayBooleanAsync.from({ content: [0, false, true] }) + ) + + await expectThrowsAsync( + async () => await TokenTypedArrayBooleanAsync.from({ content: [null, false, true] }) + ) + }) + }) + }) + } +} diff --git a/test/serialize/async/SerializeAsyncWrapper.test.ts b/test/serialize/async/SerializeAsyncWrapper.test.ts new file mode 100644 index 0000000..944420e --- /dev/null +++ b/test/serialize/async/SerializeAsyncWrapper.test.ts @@ -0,0 +1,283 @@ +import { JSONWrapperAsync, schema, SerializableAsync, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" + +@schema("https://schema.local.corp", "TokenSerializableWrapperAsync") +class TokenSerializableWrapperAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: SerializableAsync + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableWrapperAsync) + } +} + +@schema("https://schema.local.corp", "TokenSerializableObjectWrapperAsync") +class TokenSerializableObjectWrapperAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: Object + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableObjectWrapperAsync) + } +} + +@schema("https://schema.local.corp", "TokenSerializableAnyWrapperAsync") +class TokenSerializableAnyWrapperAsync extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public content: any + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenSerializableAnyWrapperAsync) + } +} + +export class SerializeAsyncWrapperTest { + public static init(): void { + describe("JSONWrapperAsync", function () { + let wrapper: JSONWrapperAsync + let serialized: string + it("should deserialize unknown content to Wrapper", async function () { + wrapper = await JSONWrapperAsync.from({ + someProperty: "someValue", + content: "someContent" + }) + expect(wrapper).instanceOf(JSONWrapperAsync) + expect(wrapper.value.someProperty).equals("someValue") + expect(wrapper.value.content).equals("someContent") + }) + + it("should serialize Wrapper content", function () { + const object: any = wrapper.toJSON() + expect(object).to.exist + expect(object["@type"]).to.not.exist + expect(object.someProperty).equals("someValue") + expect(object.content).equals("someContent") + }) + + it("should serialize Wrapper content to string", function () { + serialized = wrapper.serialize() + expect(serialized).to.equal('{"someProperty":"someValue","content":"someContent"}') + }) + + it("should deserialize Wrapper content from string", async function () { + wrapper = await JSONWrapperAsync.deserialize(serialized) + expect(wrapper).instanceOf(JSONWrapperAsync) + expect(wrapper.value.someProperty).equals("someValue") + expect(wrapper.value.content).equals("someContent") + }) + }) + + describe("JSONWrapperAsyncHierarchy", function () { + let wrapper: JSONWrapperAsync + let serialized: string + it("should deserialize unknown content to Wrapper", async function () { + wrapper = await JSONWrapperAsync.from({ + attribute: { + "@type": "Attribute", + name: "Person.firstname", + value: "outerFirstname" + }, + child: { + "@type": "JSONWrapperAsync", + someProperty: { + boolean: true, + number: 5, + array: [ + { + "@type": "Attribute", + name: "Person.firstname", + value: "innerFirstname" + }, + { + "@type": "Attribute", + name: "Person.lastname", + value: "innerLastname" + } + ] + } + }, + content: "someContent" + }) + expect(wrapper).instanceOf(JSONWrapperAsync) + const attribute = wrapper.value.attribute as Attribute + expect(attribute.name).equals("Person.firstname") + expect(attribute.value).equals("outerFirstname") + const child = wrapper.value.child + expect(child.someProperty).exist + expect(child.someProperty.boolean).equals(true) + expect(child.someProperty.number).equals(5) + expect(child.someProperty.array).is.an("array") + expect(wrapper.value.content).equals("someContent") + }) + + it("should serialize Wrapper content", function () { + const object: any = wrapper.toJSON() + expect(object).to.exist + expect(object["@type"]).to.not.exist + expect(object.attribute).to.exist + expect(object.attribute["@type"]).equals("Attribute") + expect(object.attribute.name).equals("Person.firstname") + expect(object.attribute.value).equals("outerFirstname") + expect(object.child).to.exist + expect(object.child["@type"]).equals("JSONWrapperAsync") + expect(object.child.someProperty).to.exist + expect(object.child.someProperty.boolean).equals(true) + expect(object.child.someProperty.number).equals(5) + expect(object.child.someProperty.array).is.an("array") + expect(object.content).equals("someContent") + }) + + it("should serialize Wrapper content to string", function () { + serialized = wrapper.serialize() + expect(serialized).to.equal( + '{"attribute":{"@type":"Attribute","name":"Person.firstname","value":"outerFirstname"},"child":{"@type":"JSONWrapperAsync","someProperty":{"boolean":true,"number":5,"array":[{"@type":"Attribute","name":"Person.firstname","value":"innerFirstname"},{"@type":"Attribute","name":"Person.lastname","value":"innerLastname"}]}},"content":"someContent"}' + ) + }) + + it("should deserialize Wrapper content from string", async function () { + wrapper = await JSONWrapperAsync.deserialize(serialized) + expect(wrapper).instanceOf(JSONWrapperAsync) + const attribute = wrapper.value.attribute as Attribute + expect(attribute.name).equals("Person.firstname") + expect(attribute.value).equals("outerFirstname") + const child = wrapper.value.child + expect(child.someProperty).exist + expect(child.someProperty.boolean).equals(true) + expect(child.someProperty.number).equals(5) + expect(child.someProperty.array).is.an("array") + expect(wrapper.value.content).equals("someContent") + }) + }) + + describe("TokenSerializableWrapperAsync", function () { + let wrapper: JSONWrapperAsync + let object: any + let token: TokenSerializableWrapperAsync + let serialized: string + it("should deserialize unknown wrapper content in token", async function () { + wrapper = await JSONWrapperAsync.from({ + someProperty: "someValue", + content: "someContent" + }) + + token = await TokenSerializableWrapperAsync.from({ content: wrapper }) + expect(token).instanceOf(TokenSerializableWrapperAsync) + expect(token.content).instanceOf(JSONWrapperAsync) + const anyContent = token.content as any + expect(anyContent.value.someProperty).equals("someValue") + expect(anyContent.value.content).equals("someContent") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableWrapperAsync") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.someProperty).equals("someValue") + expect(object.content.content).equals("someContent") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableWrapperAsync","content":{"someProperty":"someValue","content":"someContent"}}' + ) + }) + + it("should deserialize Token content from string", async function () { + token = (await TokenSerializableWrapperAsync.deserialize(serialized)) as TokenSerializableWrapperAsync + expect(token).instanceOf(TokenSerializableWrapperAsync) + expect(token.content).instanceOf(JSONWrapperAsync) + const anyContent = token.content as any + expect(anyContent.value.someProperty).equals("someValue") + expect(anyContent.value.content).equals("someContent") + }) + }) + + describe("TokenSerializableObjectWrapperAsync", function () { + let object: any + let token: TokenSerializableObjectWrapperAsync + let serialized: string + it("should deserialize unknown wrapper content in token", async function () { + token = await TokenSerializableObjectWrapperAsync.from({ content: { an: "object" } }) + expect(token).instanceOf(TokenSerializableObjectWrapperAsync) + expect(token.content).not.instanceOf(JSONWrapperAsync) + const anyContent = token.content as any + expect(anyContent.an).equals("object") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableObjectWrapperAsync") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.an).equals("object") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableObjectWrapperAsync","content":{"an":"object"}}' + ) + }) + + it("should deserialize Token content from string", async function () { + token = (await TokenSerializableObjectWrapperAsync.deserialize( + serialized + )) as TokenSerializableObjectWrapperAsync + expect(token).instanceOf(TokenSerializableObjectWrapperAsync) + expect(token.content).not.instanceOf(JSONWrapperAsync) + const anyContent = token.content as any + expect(anyContent.an).equals("object") + }) + }) + + describe("TokenSerializableAnyWrapperAsync", function () { + let object: any + let token: TokenSerializableAnyWrapperAsync + let serialized: string + it("should deserialize unknown wrapper content in token", async function () { + token = await TokenSerializableAnyWrapperAsync.from({ content: { an: "object" } }) + expect(token).instanceOf(TokenSerializableAnyWrapperAsync) + expect(token.content).not.instanceOf(JSONWrapperAsync) + const anyContent = token.content + expect(anyContent.an).equals("object") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableAnyWrapperAsync") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.an).equals("object") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableAnyWrapperAsync","content":{"an":"object"}}' + ) + }) + + it("should deserialize Token content from string", async function () { + token = (await TokenSerializableAnyWrapperAsync.deserialize( + serialized + )) as TokenSerializableAnyWrapperAsync + expect(token).instanceOf(TokenSerializableAnyWrapperAsync) + expect(token.content).not.instanceOf(JSONWrapperAsync) + const anyContent = token.content + expect(anyContent.an).equals("object") + }) + }) + } +} diff --git a/test/serialize/async/SerializeOnlyAsync.test.ts b/test/serialize/async/SerializeOnlyAsync.test.ts new file mode 100644 index 0000000..b2549fd --- /dev/null +++ b/test/serialize/async/SerializeOnlyAsync.test.ts @@ -0,0 +1,29 @@ +import { schema, SerializableAsync, serialize, serializeOnly } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "TokenId") +@serializeOnly("id", "string") +class TokenId extends SerializableAsync { + public notToBeSerialized = "avalue" + + @serialize() + public id: string + + public static async from(value: Object): Promise { + return await super.fromT(value, TokenId) + } +} + +export class SerializeOnlyAsyncTest { + public static init(): void { + describe("SerializeOnlyAsync", function () { + describe("TokenId", function () { + it("should only serialize the given property", async function () { + const token: any = await TokenId.from({ id: "someId" }) + const object: any = token.toJSON() + expect(object).equals("someId") + }) + }) + }) + } +} diff --git a/test/serialize/sync/ArrayInheritance.test.ts b/test/serialize/sync/ArrayInheritance.test.ts new file mode 100644 index 0000000..6a09106 --- /dev/null +++ b/test/serialize/sync/ArrayInheritance.test.ts @@ -0,0 +1,192 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +/** + * + * Serializable + * |- RelationshipTemplateArray + * |- TokenContentArray + * | |- TokenGeneric + * | |- TokenContentRelationshipTemplateArray + * | |- TokenContentStringArray + */ + +@schema("https://schema.local.corp", "RelationshipTemplateArray") +class RelationshipTemplateArray extends Serializable { + @serialize() + public template: Object + + public static deserialize(value: string): RelationshipTemplateArray { + return super.deserializeT(value, RelationshipTemplateArray) + } + + public static from(value: Object): RelationshipTemplateArray { + return super.fromT(value, RelationshipTemplateArray) + } +} + +@schema("https://schema.local.corp", "TokenContentArray") +class TokenContentArray extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public title: string + + public static deserialize(value: string): TokenContentArray { + return super.deserializeT(value, TokenContentArray) + } + + public static from(value: Object): TokenContentArray { + return super.fromT(value, TokenContentArray) + } +} + +@schema("https://schema.local.corp", "TokenContentRelationshipTemplateArray") +class TokenContentRelationshipTemplateArray extends TokenContentArray { + @serialize() + public content: RelationshipTemplateArray + + @serialize({ optional: true }) + public optionalContent: string + + public static deserialize(value: string): TokenContentRelationshipTemplateArray { + return super.deserializeT(value, TokenContentRelationshipTemplateArray) + } + + public static from(value: Object): TokenContentRelationshipTemplateArray { + return super.fromT(value, TokenContentRelationshipTemplateArray) + } +} + +@schema("https://schema.local.corp", "TokenRelationshipTemplateArray") +class TokenRelationshipTemplateArray extends Serializable { + @serialize({ deserializeStrings: true, type: TokenContentRelationshipTemplateArray }) + public templates: TokenContentRelationshipTemplateArray[] + + public static deserialize(value: string): TokenRelationshipTemplateArray { + return super.deserializeT(value, TokenRelationshipTemplateArray) + } + + public static from(value: Object): TokenRelationshipTemplateArray { + return super.fromT(value, TokenRelationshipTemplateArray) + } +} + +export class ArrayInheritanceTest { + public static init(): void { + function expectValidToken(token) { + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenRelationshipTemplateArray) + expect(token.templates).to.exist + expect(token.templates).to.be.instanceOf(Array) + expect(token.templates.length).to.equal(2) + + const item0 = token.templates[0] + expect(item0).to.be.instanceOf(Serializable) + expect(item0).to.be.instanceOf(TokenContentArray) + expect(item0).to.be.instanceOf(TokenContentRelationshipTemplateArray) + expect(item0.optionalContent).not.to.exist + expect(item0.title).to.exist + expect(item0.title).to.equal("Test") + expect(item0.notToBeSerialized).to.exist + expect(item0.notToBeSerialized).to.equal("avalue") + expect(item0.content.template).to.exist + expect(item0.content.template.myprop).to.exist + + const item1 = token.templates[1] + expect(item1).to.be.instanceOf(Serializable) + expect(item1).to.be.instanceOf(TokenContentArray) + expect(item1).to.be.instanceOf(TokenContentRelationshipTemplateArray) + expect(item1.optionalContent).to.exist + expect(item1.optionalContent).to.equal("someOptionalContent") + expect(item1.title).to.exist + expect(item1.title).to.equal("Test 2") + expect(item1.notToBeSerialized).to.exist + expect(item1.notToBeSerialized).to.equal("avalue") + expect(item1.content.template).to.exist + expect(item1.content.template.myprop).to.exist + } + describe("ArrayInheritance", function () { + describe("TokenRelationshipTemplateArray", function () { + it("from() creates instance from given interface (all objects)", function () { + const token: any = TokenRelationshipTemplateArray.from({ + templates: [ + TokenContentRelationshipTemplateArray.from({ + title: "Test", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }) + }), + TokenContentRelationshipTemplateArray.from({ + title: "Test 2", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + expectValidToken(token) + }) + + it("should toJSON() correctly", function () { + const token: any = TokenRelationshipTemplateArray.from({ + templates: [ + TokenContentRelationshipTemplateArray.from({ + title: "Test", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }) + }), + TokenContentRelationshipTemplateArray.from({ + title: "Test 2", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + const serialized = JSON.stringify(token.toJSON()) + const serializedAvailable = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArray","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + expect(serialized).to.equal(serializedAvailable) + }) + + it("should serialize correctly", function () { + const token: any = TokenRelationshipTemplateArray.from({ + templates: [ + TokenContentRelationshipTemplateArray.from({ + title: "Test", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }) + }), + TokenContentRelationshipTemplateArray.from({ + title: "Test 2", + content: RelationshipTemplateArray.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + const serialized = token.serialize() + const serializedAvailable = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArray","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + expect(serialized).to.equal(serializedAvailable) + }) + + it("should be deserialized correctly", function () { + const serialized = + '{"@context":"https://schema.local.corp","@type":"TokenRelationshipTemplateArray","templates":[{"content":{"template":{"myprop":"myvalue"}},"title":"Test"},{"content":{"template":{"myprop":"myvalue"}},"optionalContent":"someOptionalContent","title":"Test 2"}]}' + const token = Serializable.deserializeUnknown(serialized) + expectValidToken(token) + }) + }) + }) + } +} diff --git a/test/serialize/sync/Inheritance.test.ts b/test/serialize/sync/Inheritance.test.ts new file mode 100644 index 0000000..ba9ed16 --- /dev/null +++ b/test/serialize/sync/Inheritance.test.ts @@ -0,0 +1,670 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "RelationshipTemplate") +class RelationshipTemplate extends Serializable { + @serialize({ deserializeStrings: true }) + public template: Object + + public static deserialize(value: string): RelationshipTemplate { + return super.deserializeT(value, RelationshipTemplate) + } + + public static from(value: Object): RelationshipTemplate { + return super.fromT(value, RelationshipTemplate) + } +} + +@schema("https://schema.local.corp", "TokenContent") +class TokenContent extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public title: string + + public static deserialize(value: string): TokenContent { + return super.deserializeT(value, TokenContent) + } + + public static from(value: Object): TokenContent { + return super.fromT(value, TokenContent) + } +} + +@schema("https://schema.local.corp", "TokenContentGeneric") +class TokenContentGeneric extends TokenContent { + @serialize({ any: true, deserializeStrings: true }) + public content: any + + public static deserialize(value: string): TokenContentGeneric { + return super.deserializeT(value, TokenContentGeneric) + } + + public static from(value: Object): TokenContentGeneric { + return super.fromT(value, TokenContentGeneric) + } +} + +@schema("https://schema.local.corp", "TokenContentRelationshipTemplate") +class TokenContentRelationshipTemplate extends TokenContent { + @serialize({ deserializeStrings: true }) + public content: RelationshipTemplate + + @serialize({ optional: true }) + public optionalContent: string + + public static deserialize(value: string): TokenContentRelationshipTemplate { + return super.deserializeT(value, TokenContentRelationshipTemplate) + } + + public static from(value: Object): TokenContentRelationshipTemplate { + return super.fromT(value, TokenContentRelationshipTemplate) + } +} + +@schema("https://schema.local.corp", "TokenContentString") +class TokenContentString extends TokenContent { + @serialize() + public content: String + + public static deserialize(value: string): TokenContentString { + return super.deserializeT(value, TokenContentString) + } + + public static from(value: Object): TokenContentString { + return super.fromT(value, TokenContentString) + } +} + +@schema("https://schema.local.corp", "TokenRelationshipTemplates") +class TokenRelationshipTemplates extends Serializable { + @serialize({ type: TokenContentRelationshipTemplate }) + public templates: TokenContentRelationshipTemplate[] + + public static deserialize(value: string): TokenRelationshipTemplates { + return super.deserializeT(value, TokenRelationshipTemplates) + } + + public static from(value: Object): TokenRelationshipTemplates { + return super.fromT(value, TokenRelationshipTemplates) + } +} + +export class InheritanceTest { + public static init(): void { + describe("Inheritance", function () { + describe("TokenContentString", function () { + it("from() creates instance from given interface", function () { + const token: any = TokenContentString.from({ + title: "Test", + content: "someContent" + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given instance", function () { + const useToken: any = TokenContentString.from({ + title: "Test", + content: "someContent" + }) + const token: any = TokenContentString.from(useToken) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given object", function () { + const useToken: any = TokenContentString.from({ + title: "Test", + content: "someContent" + }) + const object: Object = useToken.toJSON() + const token: any = TokenContentString.from(object) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("deserialize() creates instance from given string", function () { + const token: any = TokenContentString.deserialize('{"content":"someContent","title":"Test"}') + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("serialize() creates string from given instance", function () { + const token: any = TokenContentString.deserialize('{"content":"someContent","title":"Test"}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentString","content":"someContent","title":"Test"}' + ) + }) + + it("multiple de/serialization works", function () { + let token: any = TokenContentString.deserialize('{"content":"someContent","title":"Test"}') + let string: string = token.serialize() + token = TokenContentString.deserialize(string) + string = token.serialize() + token = TokenContentString.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentString","content":"someContent","title":"Test"}' + ) + }) + }) + + describe("TokenRelationshipTemplates", function () { + it("from() creates instance from given interface (all objects)", function () { + const token: any = TokenRelationshipTemplates.from({ + templates: [ + TokenContentRelationshipTemplate.from({ + title: "Test", + content: RelationshipTemplate.from({ + template: { myprop: "myvalue" } + }) + }), + TokenContentRelationshipTemplate.from({ + title: "Test 2", + content: RelationshipTemplate.from({ + template: { myprop: "myvalue" } + }), + optionalContent: "someOptionalContent" + }) + ] + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenRelationshipTemplates) + expect(token.templates).to.exist + expect(token.templates).to.be.instanceOf(Array) + expect(token.templates.length).to.equal(2) + + const item0 = token.templates[0] + expect(item0).to.be.instanceOf(Serializable) + expect(item0).to.be.instanceOf(TokenContent) + expect(item0).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(item0.optionalContent).not.to.exist + expect(item0.title).to.exist + expect(item0.title).to.equal("Test") + expect(item0.notToBeSerialized).to.exist + expect(item0.notToBeSerialized).to.equal("avalue") + expect(item0.content.template).to.exist + expect(item0.content.template.myprop).to.exist + + const item1 = token.templates[1] + expect(item1).to.be.instanceOf(Serializable) + expect(item1).to.be.instanceOf(TokenContent) + expect(item1).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(item1.optionalContent).to.exist + expect(item1.optionalContent).to.equal("someOptionalContent") + expect(item1.title).to.exist + expect(item1.title).to.equal("Test 2") + expect(item1.notToBeSerialized).to.exist + expect(item1.notToBeSerialized).to.equal("avalue") + expect(item1.content.template).to.exist + expect(item1.content.template.myprop).to.exist + }) + }) + + describe("TokenContentRelationshipTemplate", function () { + it("from() creates instance from given interface (all objects)", function () { + const token: any = TokenContentRelationshipTemplate.from({ + title: "Test", + content: RelationshipTemplate.from({ + template: { myprop: "myvalue" } + }) + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplate) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + }) + + it("from() creates instance from given interface (with strings to deserialize)", function () { + const token: any = TokenContentRelationshipTemplate.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplate) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("from() creates instance from given instance", function () { + const useToken: any = TokenContentRelationshipTemplate.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + const token: any = TokenContentRelationshipTemplate.from(useToken) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplate) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("from() creates instance from given object", function () { + const useToken: any = TokenContentRelationshipTemplate.from({ + title: "Test", + content: '{"template":"{\\"myprop\\":\\"myvalue\\"}"}' + }) + const object: any = useToken.toJSON() + expect(object["@type"]).to.equal("TokenContentRelationshipTemplate") + expect(object["@context"]).to.equal("https://schema.local.corp") + expect(object.title).to.exist + expect(object.content).to.exist + expect(object.optionalContent).to.not.exist + expect(object.content.template).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + const token: any = TokenContentRelationshipTemplate.from(object) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplate) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("deserialize() creates instance from given string", function () { + const str = '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + const token: any = TokenContentRelationshipTemplate.deserialize(str) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token).not.to.be.instanceOf(TokenContentGeneric) + expect(token.content).to.exist + expect(token.content).to.be.instanceOf(RelationshipTemplate) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content.template).to.exist + expect(token.content.template.myprop).to.exist + expect(token.content.template.myprop).to.equal("myvalue") + }) + + it("serialize() creates string from given instance", function () { + const token: any = TokenContentString.deserialize( + '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + ) + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentString","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}","title":"Test"}' + ) + }) + + it("multiple de/serialization works", function () { + let token: any = TokenContentString.deserialize( + '{"title":"Test","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}"}' + ) + let string: string = token.serialize() + token = TokenContentString.deserialize(string) + string = token.serialize() + token = TokenContentString.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentString","content":"{\\"template\\":{\\"myprop\\":\\"myvalue\\"}}","title":"Test"}' + ) + }) + }) + + describe("TokenContentGeneric", function () { + it("from() creates instance from given interface", function () { + const token: any = TokenContentGeneric.from({ + title: "Test", + content: "someContent" + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given interface (1)", function () { + const token: any = TokenContentGeneric.from({ + title: "Test", + content: true + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given interface (2)", function () { + const token: any = TokenContentGeneric.from({ + title: "Test", + content: 5 + }) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("from() creates instance from given instance (1)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: "someContent" + }) + + const token: any = TokenContentGeneric.from(useToken) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given instance (2)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: true + }) + + const token: any = TokenContentGeneric.from(useToken) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given instance (3)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: 5 + }) + + const token: any = TokenContentGeneric.from(useToken) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("from() creates instance from given object (1)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: "someContent" + }) + + const object: Object = useToken.toJSON() + + const token: any = TokenContentGeneric.from(object) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("string") + expect(token.content).to.equal("someContent") + }) + + it("from() creates instance from given object (2)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: true + }) + + const object: Object = useToken.toJSON() + + const token: any = TokenContentGeneric.from(object) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("from() creates instance from given object (3)", function () { + const useToken: any = TokenContentGeneric.from({ + title: "Test", + content: 5 + }) + + const object: Object = useToken.toJSON() + + const token: any = TokenContentGeneric.from(object) + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.be.a("number") + expect(token.content).to.equal(5) + }) + + it("deserialize() creates instance from given string", function () { + const token: any = TokenContentGeneric.deserialize('{"title":"Test","content":"someContent"}') + + expect(token).to.be.instanceOf(Serializable) + expect(token).to.be.instanceOf(TokenContent) + expect(token).to.be.instanceOf(TokenContentGeneric) + expect(token).not.to.be.instanceOf(TokenContentRelationshipTemplate) + expect(token).not.to.be.instanceOf(TokenContentString) + expect(token.notToBeSerialized).to.exist + expect(token.notToBeSerialized).to.equal("avalue") + expect(token.title).to.exist + expect(token.title).to.equal("Test") + expect(token.content).to.exist + expect(token.content).to.equal("someContent") + }) + + it("serialize() creates string from given instance (1)", function () { + const token: any = TokenContentGeneric.deserialize('{"title":"Test","content":"someContent"}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":"someContent","title":"Test"}' + ) + }) + + it("serialize() creates string from given instance (2)", function () { + const token: any = TokenContentGeneric.deserialize('{"title":"Test","content":true}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":true,"title":"Test"}' + ) + }) + + it("serialize() creates string from given instance", function () { + const token: any = TokenContentGeneric.deserialize('{"title":"Test","content":5}') + const string: string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":5,"title":"Test"}' + ) + }) + + it("multiple de/serialization works", function () { + let token: any = TokenContentGeneric.deserialize('{"title":"Test","content":"someContent"}') + let string: string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":"someContent","title":"Test"}' + ) + }) + + it("multiple de/serialization works (1)", function () { + let token: any = TokenContentGeneric.deserialize('{"title":"Test","content":true}') + let string: string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":true,"title":"Test"}' + ) + }) + + it("multiple de/serialization works (2)", function () { + let token: any = TokenContentGeneric.deserialize('{"title":"Test","content":5}') + let string: string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + token = TokenContentGeneric.deserialize(string) + string = token.serialize() + expect(string).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenContentGeneric","content":5,"title":"Test"}' + ) + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeAnyProperty.test.ts b/test/serialize/sync/SerializeAnyProperty.test.ts new file mode 100644 index 0000000..c11555e --- /dev/null +++ b/test/serialize/sync/SerializeAnyProperty.test.ts @@ -0,0 +1,39 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "TokenSerializableContentAny") +class TokenSerializableContentAny extends Serializable { + public notToBeSerialized = "avalue" + + @serialize({ any: true }) + public content: any + + public static from(value: Object): TokenSerializableContentAny { + return super.from(value, TokenSerializableContentAny) as TokenSerializableContentAny + } +} + +export class SerializeAnyPropertyTest { + public static init(): void { + describe("SerializeAnyProperty", function () { + describe("TokenSerializableContentAny", function () { + it("should deserialize arbitrary content", function () { + const token: any = TokenSerializableContentAny.from({ content: { someProperty: "someValue" } }) + expect(token).instanceOf(TokenSerializableContentAny) + expect(token.content, "Content doesnt exist").to.exist + expect(token.content.someProperty, "Property doesnt exist").to.exist + expect(token.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", function () { + const token: any = TokenSerializableContentAny.from({ content: { someProperty: "someValue" } }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeClassProperty.test.ts b/test/serialize/sync/SerializeClassProperty.test.ts new file mode 100644 index 0000000..87765d8 --- /dev/null +++ b/test/serialize/sync/SerializeClassProperty.test.ts @@ -0,0 +1,335 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" +import { BetterAttribute } from "../../data/consumption/BetterAttribute" +import { CoreSerializable } from "../../data/core/CoreSerializable" +import { CoreId } from "../../data/core/types/CoreId" +import { expectThrows } from "../../testUtil" + +@schema("https://schema.local.corp", "TokenSerializeAttribute") +class TokenSerializeAttribute extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public content: Attribute + + public static from(value: Object): TokenSerializeAttribute { + return super.fromT(value, TokenSerializeAttribute) + } +} + +export class SerializeClassPropertyTest { + public static init(): void { + describe("SerializeClassProperty", function () { + let attr: any + let token: any + let object: any + + it("should parse correct arbitrary content", function () { + token = TokenSerializeAttribute.from({ content: { name: "firstname", value: "aFirstname" } }) + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the arbitrary content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should serialize the arbitrary content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should parse correct instantiated content", function () { + attr = Attribute.from({ name: "firstname", value: "aFirstname" }) + token = TokenSerializeAttribute.from({ content: attr }) + expect(token).to.exist + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the instantiated content", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + }) + + it("should parse correct instantiated content (subclass)", function () { + attr = BetterAttribute.from({ name: "firstname", value: "aFirstname" }) + token = TokenSerializeAttribute.from({ content: attr }) + expect(token).to.exist + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content).instanceOf(BetterAttribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the subclasses content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.exist + expect(object.content["@type"]).equals("BetterAttribute") + expect(object.content["@context"]).to.exist + }) + + it("should parse correct serialized content again (subclass)", function () { + token = TokenSerializeAttribute.from(object) + expect(token).to.exist + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content).instanceOf(BetterAttribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + }) + + it("should serialize the subclasses content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.exist + expect(object.content["@type"]).equals("BetterAttribute") + expect(object.content["@context"]).to.exist + }) + + it("should not parse additional arbitrary content", function () { + token = TokenSerializeAttribute.from({ + content: { + name: "firstname", + value: "aFirstname", + someAdditonalArbitraryProperty: "someAdditonalArbitraryValue" + }, + someAdditonalArbitraryProperty: "someAdditonalArbitraryValue" + }) + expect(token).to.exist + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + expect(token.content.someAdditonalArbitraryProperty).to.not.exist + expect(token.someAdditonalArbitraryProperty).to.not.exist + }) + + it("should not serialize the additional arbitrary content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not serialize the additional arbitrary content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not parse additional instantiated content", function () { + attr = Attribute.from({ name: "firstname", value: "aFirstname" }) + attr.additionalContent = "someAdditionalContent" + token = TokenSerializeAttribute.from({ + content: attr, + additionalContent: "someAdditionalContent" + }) + expect(token).to.exist + expect(token).instanceOf(Serializable) + expect(token).instanceOf(TokenSerializeAttribute) + expect(token.content).instanceOf(Serializable) + expect(token.content).instanceOf(CoreSerializable) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).equals("aFirstname") + expect(token.additionalContent).to.not.exist + // This is intentional, if somebody sets an instance here, it is actually referenced + // and not copied, thus the arbritrary properties are copied too (for the object) + expect(token.content.additionalContent).to.exist + }) + + it("should not serialize the additional instantiated content (verbose)", function () { + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not serialize the additional instantiated content (non-verbose)", function () { + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not serialize non-known arbitrary content (verbose)", function () { + token.content.someprop = "test" + token.someprop = "test" + object = token.toJSON() + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.exist + expect(object["@type"]).equals("TokenSerializeAttribute") + expect(object["@context"]).to.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not serialize non-known arbitrary content (non-verbose)", function () { + token.content.someprop = "test" + token.someprop = "test" + object = token.toJSON(false) + expect(object).is.a("object") + expect(object).not.instanceOf(Serializable) + expect(object).not.instanceOf(TokenSerializeAttribute) + expect(object["@type"]).to.not.exist + expect(object["@context"]).to.not.exist + expect(object.content).to.exist + expect(object.content.name).equals("firstname") + expect(object.content.value).equals("aFirstname") + expect(object.content["@type"]).to.not.exist + expect(object.content["@context"]).to.not.exist + expect(object.content.someprop).to.not.exist + expect(object.someprop).to.not.exist + }) + + it("should not parse incorrect instantiated content", function () { + const id = CoreId.from("Test") + expectThrows(() => { + TokenSerializeAttribute.from({ + content: id + }) + }) + + expectThrows(() => { + TokenSerializeAttribute.from({ + conten: id + }) + }) + }) + + it("should not parse incorrect arbitrary content", function () { + expectThrows(() => { + TokenSerializeAttribute.from({ + content: { + someIncorrectArbitraryProperty: "someIncorrectArbitraryValue", + value: "someCorrectValue" + } + }) + }) + + expectThrows(() => { + TokenSerializeAttribute.from({ + conten: { + someIncorrectArbitraryProperty: "someIncorrectArbitraryValue", + value: "someCorrectValue" + } + }) + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeEnforceStringProperty.test.ts b/test/serialize/sync/SerializeEnforceStringProperty.test.ts new file mode 100644 index 0000000..5ef5d54 --- /dev/null +++ b/test/serialize/sync/SerializeEnforceStringProperty.test.ts @@ -0,0 +1,74 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" + +@schema("https://schema.local.corp", "TokenSerializableEnforceString") +class TokenSerializableEnforceString extends Serializable { + public notToBeSerialized = "avalue" + + @serialize({ enforceString: true }) + public content: Attribute + + public static from(value: Object): TokenSerializableEnforceString { + return super.fromT(value, TokenSerializableEnforceString) + } +} + +export class SerializeEnforceStringPropertyTest { + public static init(): void { + describe("SerializeEnforceStringProperty", function () { + let token: TokenSerializableEnforceString + + it("should create from object", function () { + const attribute = Attribute.from({ name: "firstname", value: "test" }) + token = TokenSerializableEnforceString.from({ content: attribute }) + expect(token).instanceOf(TokenSerializableEnforceString) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).is.a("string") + expect(token.content.value).equals("test") + }) + + it("should serialize as JSON", function () { + const tokenAsJSON = token.toJSON() as any + + expect(tokenAsJSON).to.be.a("object") + expect(tokenAsJSON).not.to.be.instanceOf(TokenSerializableEnforceString) + expect(tokenAsJSON).to.exist + expect(tokenAsJSON.content).to.be.a("string") + expect(tokenAsJSON.content).to.equal('{"name":"firstname","value":"test"}') + }) + + it("should deserialize from object (as string)", function () { + token = TokenSerializableEnforceString.from(token.toJSON()) + expect(token).instanceOf(TokenSerializableEnforceString) + expect(token.content).instanceOf(Attribute) + expect(token.content.name).equals("firstname") + expect(token.content.value).is.a("string") + expect(token.content.value).equals("test") + }) + + it("should serialize as string", function () { + const serializedToken = token.serialize() + + expect(serializedToken).to.be.a("string") + expect(serializedToken).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableEnforceString","content":"{\\"name\\":\\"firstname\\",\\"value\\":\\"test\\"}"}' + ) + }) + + it("should deserialize from string", function () { + const tokenAfterDeserialize = TokenSerializableEnforceString.deserializeT( + token.serialize(), + TokenSerializableEnforceString + ) + + expect(tokenAfterDeserialize).instanceOf(TokenSerializableEnforceString) + expect(tokenAfterDeserialize.content).instanceOf(Attribute) + expect(tokenAfterDeserialize.content.name).equals("firstname") + expect(tokenAfterDeserialize.content.value).is.a("string") + expect(tokenAfterDeserialize.content.value).equals("test") + }) + }) + } +} diff --git a/test/serialize/sync/SerializeGenericProperty.test.ts b/test/serialize/sync/SerializeGenericProperty.test.ts new file mode 100644 index 0000000..815be4c --- /dev/null +++ b/test/serialize/sync/SerializeGenericProperty.test.ts @@ -0,0 +1,70 @@ +import { JSONWrapper, schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" + +@schema("https://schema.local.corp", "TokenSerializableContentGenericProperty") +class TokenSerializableContentGenericProperty extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public content: Serializable + + public static from(value: Object): TokenSerializableContentGenericProperty { + return super.fromT(value, TokenSerializableContentGenericProperty) + } +} + +export class SerializeGenericPropertyTest { + public static init(): void { + describe("SerializeGenericProperty", function () { + describe("TokenSerializableContentGenericProperty", function () { + it("should deserialize arbitrary content", function () { + const token: any = TokenSerializableContentGenericProperty.from({ + content: { someProperty: "someValue" } + }) + expect(token).instanceOf(TokenSerializableContentGenericProperty) + expect(token.content).instanceOf(JSONWrapper) + expect(token.content.value, "Content doesnt exist").to.exist + expect(token.content.value.someProperty, "Property doesnt exist").to.exist + expect(token.content.value.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", function () { + const token: any = TokenSerializableContentGenericProperty.from({ + content: { someProperty: "someValue" } + }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + expect(object.content["@type"]).not.exist + }) + }) + + describe("Attribute", function () { + it("should deserialize other classes", function () { + const attribute = Attribute.from({ name: "firstname", value: "test" }) + const token: any = TokenSerializableContentGenericProperty.from({ content: attribute }) + expect(token).to.exist + expect(token.content).instanceOf(Attribute) + expect((token.content as Attribute).name).equals("firstname") + expect((token.content as Attribute).value).is.a("string") + expect((token.content as Attribute).value).equals("test") + }) + + it("should serialize other classes (and output type information)", function () { + const attribute = Attribute.from({ name: "firstname", value: "test" }) + const token: any = TokenSerializableContentGenericProperty.from({ content: attribute }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content).is.not.instanceOf(Attribute) + expect(object.content.name).equals("firstname") + expect(object.content.value).is.a("string") + expect(object.content.value).equals("test") + expect(object.content["@type"]).equals("Attribute") + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeMultiType.test.ts b/test/serialize/sync/SerializeMultiType.test.ts new file mode 100644 index 0000000..de8f85a --- /dev/null +++ b/test/serialize/sync/SerializeMultiType.test.ts @@ -0,0 +1,193 @@ +import { PrimitiveType, schema, Serializable, serialize, validate } from "@js-soft/ts-serval" +import { expect } from "chai" +import { expectThrows } from "../../testUtil" + +interface ITokenContentMulti { + value: string | number | boolean +} + +@schema("https://schema.local.corp", "TokenContentMulti") +class TokenContentMulti extends Serializable implements ITokenContentMulti { + public notToBeSerialized = "avalue" + + @validate({ allowedTypes: [PrimitiveType.String, PrimitiveType.Number, PrimitiveType.Boolean] }) + @serialize() + public value: string | number | boolean + + public static from(value: ITokenContentMulti): TokenContentMulti { + return super.fromT(value, TokenContentMulti) + } +} + +export class SerializeMultiTypeTest { + public static init(): void { + describe("SerializeMultiType", function () { + it("should serialize the given property as string", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: "string" }) + const object: any = token.toJSON() + expect(object.value).be.a("string") + expect(object.value).equals("string") + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("string") + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("string") + }) + + it("should serialize the given property as string (empty)", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: "" }) + const object: any = token.toJSON() + expect(object.value).be.a("string") + expect(object.value).equals("") + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("") + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("string") + expect(object.value).equals("") + }) + + it("should serialize the given property as boolean (true)", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: true }) + const object: any = token.toJSON() + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(true) + }) + + it("should serialize the given property as boolean (false)", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: false }) + const object: any = token.toJSON() + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("boolean") + expect(object.value).equals(false) + }) + + it("should serialize the given property as number", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: 55.5 }) + const object: any = token.toJSON() + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(55.5) + }) + + it("should serialize the given property as number (zero)", function () { + const token: TokenContentMulti = TokenContentMulti.from({ value: 0 }) + const object: any = token.toJSON() + expect(object.value).be.a("number") + expect(object.value).equals(0) + + const parsed: TokenContentMulti = TokenContentMulti.from(object) + expect(parsed).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized2 = parsed.serialize() + const parsed2: TokenContentMulti = TokenContentMulti.deserializeT(serialized2, TokenContentMulti) + expect(parsed2).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized3 = parsed2.serialize() + const parsed3 = Serializable.deserializeUnknown(serialized3) + expect(parsed3).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(0) + const serialized4 = parsed3.toJSON() + const parsed4 = Serializable.fromUnknown(serialized4) + expect(parsed4).instanceOf(TokenContentMulti) + expect(object.value).be.a("number") + expect(object.value).equals(0) + }) + + it("should not parse properties with wrong type", function () { + const value: any = { value: ["a", "b"] } + expectThrows(() => TokenContentMulti.from(value), "TokenContentMulti.value") + }) + }) + } +} diff --git a/test/serialize/sync/SerializeOnly.test.ts b/test/serialize/sync/SerializeOnly.test.ts new file mode 100644 index 0000000..1bbf657 --- /dev/null +++ b/test/serialize/sync/SerializeOnly.test.ts @@ -0,0 +1,29 @@ +import { schema, Serializable, serialize, serializeOnly } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "TokenId") +@serializeOnly("id", "string") +class TokenId extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public id: string + + public static from(value: Object): TokenId { + return super.fromT(value, TokenId) + } +} + +export class SerializeOnlyTest { + public static init(): void { + describe("SerializeOnly", function () { + describe("TokenId", function () { + it("should only serialize the given property", function () { + const token: any = TokenId.from({ id: "someId" }) + const object: any = token.toJSON() + expect(object).equals("someId") + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeTypedArray.test.ts b/test/serialize/sync/SerializeTypedArray.test.ts new file mode 100644 index 0000000..d8e5714 --- /dev/null +++ b/test/serialize/sync/SerializeTypedArray.test.ts @@ -0,0 +1,140 @@ +import { schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { expectThrows } from "../../testUtil" + +@schema("https://schema.local.corp", "TokenTypedArrayString") +class TokenTypedArrayString extends Serializable { + public notToBeSerialized = "avalue" + + @serialize({ type: String }) + public content: string[] + + public static from(value: Object): TokenTypedArrayString { + return super.fromT(value, TokenTypedArrayString) + } +} + +@schema("https://schema.local.corp", "TokenTypedArrayNumber") +class TokenTypedArrayNumber extends Serializable { + public notToBeSerialized = "avalue" + + @serialize({ type: Number }) + public content: number[] + + public static from(value: Object): TokenTypedArrayNumber { + return super.fromT(value, TokenTypedArrayNumber) + } +} + +@schema("https://schema.local.corp", "TokenTypedArrayBoolean") +class TokenTypedArrayBoolean extends Serializable { + public notToBeSerialized = "avalue" + + @serialize({ type: Boolean }) + public content: boolean[] + + public static from(value: Object): TokenTypedArrayBoolean { + return super.fromT(value, TokenTypedArrayBoolean) + } +} + +export class SerializeTypedArrayTest { + public static init(): void { + describe("SerializeTypedArray", function () { + describe("TokenTypedArrayString", function () { + let token: TokenTypedArrayString + it("should deserialize string arrays", function () { + token = TokenTypedArrayString.from({ content: ["Test1", "Test2", ""] }) + expect(token).to.be.instanceOf(TokenTypedArrayString) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals("Test1") + expect(token.content[1]).equals("Test2") + expect(token.content[2]).equals("") + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayString) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals("Test1") + expect(object.content[1]).equals("Test2") + expect(object.content[2]).equals("") + }) + + it("should not deserialize non-string arrays", function () { + expectThrows(() => { + token = TokenTypedArrayString.from({ content: [true, "Test2", "Test3"] }) + }) + + expectThrows(() => { + token = TokenTypedArrayString.from({ content: [null, "Test2", "Test3"] }) + }) + }) + }) + + describe("TokenTypedArrayNumber", function () { + let token: TokenTypedArrayNumber + it("should deserialize number arrays", function () { + token = TokenTypedArrayNumber.from({ content: [5, -1.5, 0] }) + expect(token).to.be.instanceOf(TokenTypedArrayNumber) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals(5) + expect(token.content[1]).equals(-1.5) + expect(token.content[2]).equals(0) + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayNumber) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals(5) + expect(object.content[1]).equals(-1.5) + expect(object.content[2]).equals(0) + }) + + it("should not deserialize non-number arrays", function () { + expectThrows(() => { + token = TokenTypedArrayNumber.from({ content: [true, -1.5, "Test3"] }) + }) + + expectThrows(() => { + token = TokenTypedArrayNumber.from({ content: [null, -1.5, "Test3"] }) + }) + }) + }) + + describe("TokenTypedArrayBoolean", function () { + let token: TokenTypedArrayBoolean + it("should deserialize boolean arrays", function () { + token = TokenTypedArrayBoolean.from({ content: [true, false, true] }) + expect(token).to.be.instanceOf(TokenTypedArrayBoolean) + expect(token.content).to.be.an("array") + expect(token.content[0]).equals(true) + expect(token.content[1]).equals(false) + expect(token.content[2]).equals(true) + }) + + it("should serialize arbitrary content", function () { + const object: any = token.toJSON() + expect(object).to.exist + expect(object).not.to.be.instanceOf(TokenTypedArrayBoolean) + expect(object.content).to.be.an("array") + expect(object.content[0]).equals(true) + expect(object.content[1]).equals(false) + expect(object.content[2]).equals(true) + }) + + it("should not deserialize non-boolean arrays", function () { + expectThrows(() => { + token = TokenTypedArrayBoolean.from({ content: [0, false, true] }) + }) + expectThrows(() => { + token = TokenTypedArrayBoolean.from({ content: [null, false, true] }) + }) + }) + }) + }) + } +} diff --git a/test/serialize/sync/SerializeWrapper.test.ts b/test/serialize/sync/SerializeWrapper.test.ts new file mode 100644 index 0000000..ca7421b --- /dev/null +++ b/test/serialize/sync/SerializeWrapper.test.ts @@ -0,0 +1,280 @@ +import { JSONWrapper, schema, Serializable, serialize } from "@js-soft/ts-serval" +import { expect } from "chai" +import { Attribute } from "../../data/consumption/Attribute" + +@schema("https://schema.local.corp", "TokenSerializableWrapper") +class TokenSerializableWrapper extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public content: Serializable + + public static from(value: Object): TokenSerializableWrapper { + return super.fromT(value, TokenSerializableWrapper) + } +} + +@schema("https://schema.local.corp", "TokenSerializableObjectWrapper") +class TokenSerializableObjectWrapper extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public content: Object + + public static from(value: Object): TokenSerializableObjectWrapper { + return super.fromT(value, TokenSerializableObjectWrapper) + } +} + +@schema("https://schema.local.corp", "TokenSerializableAnyWrapper") +class TokenSerializableAnyWrapper extends Serializable { + public notToBeSerialized = "avalue" + + @serialize() + public content: any + + public static from(value: Object): TokenSerializableAnyWrapper { + return super.fromT(value, TokenSerializableAnyWrapper) + } +} + +export class SerializeWrapperTest { + public static init(): void { + describe("JSONWrapper", function () { + let wrapper: JSONWrapper + let serialized: string + + it("should deserialize unknown content to Wrapper", function () { + wrapper = JSONWrapper.from({ + someProperty: "someValue", + content: "someContent" + }) + expect(wrapper).instanceOf(JSONWrapper) + expect(wrapper.value.someProperty).equals("someValue") + expect(wrapper.value.content).equals("someContent") + }) + + it("should serialize Wrapper content", function () { + const object: any = wrapper.toJSON() + expect(object).to.exist + expect(object["@type"]).to.not.exist + expect(object.someProperty).equals("someValue") + expect(object.content).equals("someContent") + }) + + it("should serialize Wrapper content to string", function () { + serialized = wrapper.serialize() + expect(serialized).to.equal('{"someProperty":"someValue","content":"someContent"}') + }) + + it("should deserialize Wrapper content from string", function () { + wrapper = JSONWrapper.deserialize(serialized) + expect(wrapper).instanceOf(JSONWrapper) + expect(wrapper.value.someProperty).equals("someValue") + expect(wrapper.value.content).equals("someContent") + }) + }) + + describe("JSONWrapperHierarchy", function () { + let wrapper: JSONWrapper + let serialized: string + it("should deserialize unknown content to Wrapper", function () { + wrapper = JSONWrapper.from({ + attribute: { + "@type": "Attribute", + name: "Person.firstname", + value: "outerFirstname" + }, + child: { + "@type": "JSONWrapper", + someProperty: { + boolean: true, + number: 5, + array: [ + { + "@type": "Attribute", + name: "Person.firstname", + value: "innerFirstname" + }, + { + "@type": "Attribute", + name: "Person.lastname", + value: "innerLastname" + } + ] + } + }, + content: "someContent" + }) + expect(wrapper).instanceOf(JSONWrapper) + const attribute = wrapper.value.attribute as Attribute + expect(attribute.name).equals("Person.firstname") + expect(attribute.value).equals("outerFirstname") + const child = wrapper.value.child + expect(child.someProperty).exist + expect(child.someProperty.boolean).equals(true) + expect(child.someProperty.number).equals(5) + expect(child.someProperty.array).is.an("array") + expect(wrapper.value.content).equals("someContent") + }) + + it("should serialize Wrapper content", function () { + const object: any = wrapper.toJSON() + expect(object).to.exist + expect(object["@type"]).to.not.exist + expect(object.attribute).to.exist + expect(object.attribute["@type"]).equals("Attribute") + expect(object.attribute.name).equals("Person.firstname") + expect(object.attribute.value).equals("outerFirstname") + expect(object.child).to.exist + expect(object.child["@type"]).equals("JSONWrapper") + expect(object.child.someProperty).to.exist + expect(object.child.someProperty.boolean).equals(true) + expect(object.child.someProperty.number).equals(5) + expect(object.child.someProperty.array).is.an("array") + expect(object.content).equals("someContent") + }) + + it("should serialize Wrapper content to string", function () { + serialized = wrapper.serialize() + expect(serialized).to.equal( + '{"attribute":{"@type":"Attribute","name":"Person.firstname","value":"outerFirstname"},"child":{"@type":"JSONWrapper","someProperty":{"boolean":true,"number":5,"array":[{"@type":"Attribute","name":"Person.firstname","value":"innerFirstname"},{"@type":"Attribute","name":"Person.lastname","value":"innerLastname"}]}},"content":"someContent"}' + ) + }) + + it("should deserialize Wrapper content from string", function () { + wrapper = JSONWrapper.deserialize(serialized) + expect(wrapper).instanceOf(JSONWrapper) + const attribute = wrapper.value.attribute as Attribute + expect(attribute.name).equals("Person.firstname") + expect(attribute.value).equals("outerFirstname") + const child = wrapper.value.child + expect(child.someProperty).exist + expect(child.someProperty.boolean).equals(true) + expect(child.someProperty.number).equals(5) + expect(child.someProperty.array).is.an("array") + expect(wrapper.value.content).equals("someContent") + }) + }) + + describe("TokenSerializableWrapper", function () { + let wrapper: JSONWrapper + let object: any + let token: TokenSerializableWrapper + let serialized: string + it("should deserialize unknown wrapper content in token", function () { + wrapper = JSONWrapper.from({ + someProperty: "someValue", + content: "someContent" + }) + + token = TokenSerializableWrapper.from({ content: wrapper }) + expect(token).instanceOf(TokenSerializableWrapper) + expect(token.content).instanceOf(JSONWrapper) + const anyContent = token.content as any + expect(anyContent.value.someProperty).equals("someValue") + expect(anyContent.value.content).equals("someContent") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableWrapper") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.someProperty).equals("someValue") + expect(object.content.content).equals("someContent") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableWrapper","content":{"someProperty":"someValue","content":"someContent"}}' + ) + }) + + it("should deserialize Token content from string", function () { + token = TokenSerializableWrapper.deserialize(serialized) as TokenSerializableWrapper + expect(token).instanceOf(TokenSerializableWrapper) + expect(token.content).instanceOf(JSONWrapper) + const anyContent = token.content as any + expect(anyContent.value.someProperty).equals("someValue") + expect(anyContent.value.content).equals("someContent") + }) + }) + + describe("TokenSerializableObjectWrapper", function () { + let object: any + let token: TokenSerializableObjectWrapper + let serialized: string + it("should deserialize unknown wrapper content in token", function () { + token = TokenSerializableObjectWrapper.from({ content: { an: "object" } }) + expect(token).instanceOf(TokenSerializableObjectWrapper) + expect(token.content).not.instanceOf(JSONWrapper) + const anyContent = token.content as any + expect(anyContent.an).equals("object") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableObjectWrapper") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.an).equals("object") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableObjectWrapper","content":{"an":"object"}}' + ) + }) + + it("should deserialize Token content from string", function () { + token = TokenSerializableObjectWrapper.deserialize(serialized) as TokenSerializableObjectWrapper + expect(token).instanceOf(TokenSerializableObjectWrapper) + expect(token.content).not.instanceOf(JSONWrapper) + const anyContent = token.content as any + expect(anyContent.an).equals("object") + }) + }) + + describe("TokenSerializableAnyWrapper", function () { + let object: any + let token: TokenSerializableAnyWrapper + let serialized: string + it("should deserialize unknown wrapper content in token", function () { + token = TokenSerializableAnyWrapper.from({ content: { an: "object" } }) + expect(token).instanceOf(TokenSerializableAnyWrapper) + expect(token.content).not.instanceOf(JSONWrapper) + const anyContent = token.content + expect(anyContent.an).equals("object") + }) + + it("should serialize Token", function () { + object = token.toJSON() + expect(object).to.exist + expect(object["@type"]).to.equal("TokenSerializableAnyWrapper") + expect(object.content).to.exist + expect(object.content["@type"]).to.not.exist + expect(object.content.an).equals("object") + }) + + it("should serialize Token content to string", function () { + serialized = token.serialize() + expect(serialized).to.equal( + '{"@context":"https://schema.local.corp","@type":"TokenSerializableAnyWrapper","content":{"an":"object"}}' + ) + }) + + it("should deserialize Token content from string", function () { + token = TokenSerializableAnyWrapper.deserialize(serialized) as TokenSerializableAnyWrapper + expect(token).instanceOf(TokenSerializableAnyWrapper) + expect(token.content).not.instanceOf(JSONWrapper) + const anyContent = token.content + expect(anyContent.an).equals("object") + }) + }) + } +} diff --git a/test/testUtil.ts b/test/testUtil.ts new file mode 100644 index 0000000..99cdf37 --- /dev/null +++ b/test/testUtil.ts @@ -0,0 +1,33 @@ +import { expect } from "chai" + +export function expectThrows(method: Function, errorMessage = ""): void { + let error: Error | undefined + try { + if (typeof method === "function") { + method() + } + } catch (err) { + error = err + } + expect(error).to.be.an("Error") + if (errorMessage) { + expect(error!.message.startsWith(errorMessage)).to.be.true + } +} + +export async function expectThrowsAsync(method: Function | Promise, errorMessage = ""): Promise { + let error: Error | undefined + try { + if (typeof method === "function") { + await method() + } else { + await method + } + } catch (err) { + error = err + } + expect(error).to.be.an("Error") + if (errorMessage) { + expect(error!.message).to.match(new RegExp(`^${errorMessage}`)) + } +} diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..6104c75 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "sourceMap": true, + "declaration": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "outDir": "../lib-test", + "strict": false, // Unfortunately strict mode has problems with decorators accessing the this context within getters/setters + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "moduleResolution": "node", + "forceConsistentCasingInFileNames": true, + "downlevelIteration": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "lib": ["es2017", "dom"], + "typeRoots": ["../node_modules/@types"], + "baseUrl": "../", + "paths": { + "@js-soft/ts-serval": ["src"] + } + }, + "include": ["**/*.ts"], + "exclude": [] +} diff --git a/test/usage/Core.test.ts b/test/usage/Core.test.ts new file mode 100644 index 0000000..49cd143 --- /dev/null +++ b/test/usage/Core.test.ts @@ -0,0 +1,35 @@ +import { expect } from "chai" +import { Certificate } from "../data/core/Certificate" +import { CryptoSignature } from "../data/crypto/CryptoSignature" + +export class CoreTest { + public static init(): void { + describe("Core", function () { + describe("Certificate", function () { + it("should deserialize and serialize correctly", async function () { + const certObject: any = { + content: + '{"@context":"https://schema.corp","@type":"CertificateContent","constraints":[{}],"issuedAt":"2021-01-05T11:04:09.819Z","issuer":"id1H9jKjY5RSXFzJVftGcQ48Y3oX43EEdBH4","issuerData":{},"items":[{},{},{}],"subject":"id1NGoWuEFWrjNZsAjNqy13Qzs7iqVAWoyFU","subjectPublicKey":{"pub":"amEeyBzmO971T5PeVgrY-L9goH3v5Kb1a2I9LeSAn30","alg":3}}', + signature: { + sig: "V8wjmY2YW4i0WEZa_RaWLrYNapgMyNQhCBQVpRabpZc4VYarytu4OaU3-XepHD2BfV4MaNtKTxybw_0F0hqbBg", + alg: 2 + } + } + const cert = await Certificate.from(certObject) + expect(cert).instanceOf(Certificate) + expect(cert.content).to.be.a("string") + expect(cert.signature).instanceOf(CryptoSignature) + + const serialized = + '{"@context":"https://schema.corp","@type":"Certificate","content":"{\\"@context\\":\\"https://schema.corp\\",\\"@type\\":\\"CertificateContent\\",\\"constraints\\":[{}],\\"issuedAt\\":\\"2021-01-05T11:04:09.819Z\\",\\"issuer\\":\\"id1H9jKjY5RSXFzJVftGcQ48Y3oX43EEdBH4\\",\\"issuerData\\":{},\\"items\\":[{},{},{}],\\"subject\\":\\"id1NGoWuEFWrjNZsAjNqy13Qzs7iqVAWoyFU\\",\\"subjectPublicKey\\":{\\"pub\\":\\"amEeyBzmO971T5PeVgrY-L9goH3v5Kb1a2I9LeSAn30\\",\\"alg\\":3}}","signature":{"sig":"V8wjmY2YW4i0WEZa/RaWLrYNapgMyNQhCBQVpRabpZc4VYarytu4OaU3+XepHD2BfV4MaNtKTxybw/0F0hqbBg==","alg":2}}' + expect(cert.serialize()).to.equal(serialized) + + const cert2 = await Certificate.deserialize(serialized) + expect(cert2).instanceOf(Certificate) + expect(cert2.content).to.be.a("string") + expect(cert2.signature).instanceOf(CryptoSignature) + }) + }) + }) + } +} diff --git a/test/validate/ValidateAnyProperty.test.ts b/test/validate/ValidateAnyProperty.test.ts new file mode 100644 index 0000000..141e394 --- /dev/null +++ b/test/validate/ValidateAnyProperty.test.ts @@ -0,0 +1,236 @@ +import { schema, Serializable, serialize, validate } from "@js-soft/ts-serval" +import { expect } from "chai" +import { expectThrows } from "../testUtil" + +@schema("https://schema.local.corp", "ValidateTokenSerializableContentAny") +class ValidateTokenSerializableContentAny extends Serializable { + public notToBeSerialized = "avalue" + + @validate() + @serialize({ any: true }) + public content: any + + public static from(value: Object): ValidateTokenSerializableContentAny { + return super.fromT(value, ValidateTokenSerializableContentAny) + } +} + +@schema("https://schema.local.corp", "ValidateTokenSerializableContentAnyNullable") +class ValidateTokenSerializableContentAnyNullable extends Serializable { + public notToBeSerialized = "avalue" + + @validate({ nullable: true }) + @serialize({ any: true }) + public content: any + + public static from(value: Object): ValidateTokenSerializableContentAnyNullable { + return super.fromT(value, ValidateTokenSerializableContentAnyNullable) + } +} + +export class ValidateAnyPropertyTest { + public static init(): void { + describe("ValidateAnyProperty", function () { + describe("ValidateTokenSerializableContentAny", function () { + it("should deserialize arbitrary content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ + content: { someProperty: "someValue" } + }) + expect(token).to.exist + expect(token.content, "Content doesnt exist").to.exist + expect(token.content.someProperty, "Property doesnt exist").to.exist + expect(token.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ + content: { someProperty: "someValue" } + }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should deserialize boolean content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: true }) + expect(token).instanceOf(ValidateTokenSerializableContentAny) + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("should serialize boolean content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: false }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAny) + expect(object.content).to.be.a("boolean") + expect(object.content).to.equal(false) + }) + + it("should deserialize number content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: 45 }) + expect(token).instanceOf(ValidateTokenSerializableContentAny) + expect(token.content).to.be.a("number") + expect(token.content).to.equal(45) + }) + + it("should serialize number content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: 0 }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAny) + expect(object.content).to.be.a("number") + expect(object.content).to.equal(0) + }) + + it("should deserialize string content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: "Test" }) + expect(token).instanceOf(ValidateTokenSerializableContentAny) + expect(token.content).to.be.a("string") + expect(token.content).to.equal("Test") + }) + + it("should serialize string content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: "" }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAny) + expect(object.content).to.be.a("string") + expect(object.content).to.equal("") + }) + + it("should deserialize array content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ + content: [5, "Test2", null, true, [false], { some: "object" }] + }) + expect(token).instanceOf(ValidateTokenSerializableContentAny) + expect(token.content).to.be.an("array") + expect(token.content[0]).to.equal(5) + expect(token.content[1]).to.equal("Test2") + expect(token.content[2]).to.equal(null) + expect(token.content[3]).to.equal(true) + expect(token.content[4]).to.be.an("array") + expect(token.content[4].length).to.equal(1) + expect(token.content[5]).to.be.an("object") + expect(token.content[5].some).to.equal("object") + }) + + it("should serialize array content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ + content: [5, "Test2", null, true, [false], { some: "object" }] + }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAny) + expect(object.content).to.be.an("array") + expect(object.content[0]).to.equal(5) + expect(object.content[1]).to.equal("Test2") + expect(object.content[2]).to.equal(null) + expect(object.content[3]).to.equal(true) + expect(object.content[4]).to.be.an("array") + expect(object.content[4].length).to.equal(1) + expect(object.content[5]).to.be.an("object") + expect(object.content[5].some).to.equal("object") + }) + + it("should not deserialize null content", function () { + expectThrows(() => ValidateTokenSerializableContentAny.from({ content: null })) + }) + + it("should not set null content", function () { + const token: any = ValidateTokenSerializableContentAny.from({ content: "" }) + expectThrows(() => { + token.content = null + }) + }) + }) + + describe("ValidateTokenSerializableContentAnyNullable", function () { + it("should deserialize arbitrary content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ + content: { someProperty: "someValue" } + }) + expect(token).to.exist + expect(token.content, "Content doesnt exist").to.exist + expect(token.content.someProperty, "Property doesnt exist").to.exist + expect(token.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ + content: { someProperty: "someValue" } + }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should deserialize boolean content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: true }) + expect(token).instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(token.content).to.be.a("boolean") + expect(token.content).to.equal(true) + }) + + it("should serialize boolean content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: false }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(object.content).to.be.a("boolean") + expect(object.content).to.equal(false) + }) + + it("should deserialize number content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: 45 }) + expect(token).instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(token.content).to.be.a("number") + expect(token.content).to.equal(45) + }) + + it("should serialize number content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: 0 }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(object.content).to.be.a("number") + expect(object.content).to.equal(0) + }) + + it("should deserialize string content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: "Test" }) + expect(token).instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(token.content).to.be.a("string") + expect(token.content).to.equal("Test") + }) + + it("should serialize string content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: "" }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(object.content).to.be.a("string") + expect(object.content).to.equal("") + }) + + it("should deserialize null content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: null }) + expect(token).instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(token.content).to.equal(null) + }) + + it("should serialize null content", function () { + const token: any = ValidateTokenSerializableContentAnyNullable.from({ content: null }) + const object: any = token.toJSON() + expect(object).to.be.a("object") + expect(object).not.to.be.instanceOf(ValidateTokenSerializableContentAnyNullable) + expect(object.content).to.equal(null) + }) + }) + }) + } +} diff --git a/test/validate/ValidateGenericProperty.test.ts b/test/validate/ValidateGenericProperty.test.ts new file mode 100644 index 0000000..9dc8d75 --- /dev/null +++ b/test/validate/ValidateGenericProperty.test.ts @@ -0,0 +1,41 @@ +import { JSONWrapper, schema, Serializable, serialize, validate } from "@js-soft/ts-serval" +import { expect } from "chai" + +@schema("https://schema.local.corp", "ValidateTokenSerializableGeneric") +class ValidateTokenSerializableGeneric extends Serializable { + public notToBeSerialized = "avalue" + + @validate() + @serialize() + public content: Serializable + + public static from(value: Object): ValidateTokenSerializableGeneric { + return super.fromT(value, ValidateTokenSerializableGeneric) + } +} + +export class ValidateGenericPropertyTest { + public static init(): void { + describe("ValidateGenericProperty", function () { + describe("ValidateTokenSerializableGeneric", function () { + it("should deserialize arbitrary content", function () { + const token: any = ValidateTokenSerializableGeneric.from({ content: { someProperty: "someValue" } }) + expect(token).to.exist + expect(token.content).instanceOf(JSONWrapper) + expect(token.content.value, "Content doesnt exist").to.exist + expect(token.content.value.someProperty, "Property doesnt exist").to.exist + expect(token.content.value.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + + it("should serialize arbitrary content", function () { + const token: any = ValidateTokenSerializableGeneric.from({ content: { someProperty: "someValue" } }) + const object: any = token.toJSON() + expect(object).to.exist + expect(object.content, "Content doesnt exist").to.exist + expect(object.content.someProperty, "Property doesnt exist").to.exist + expect(object.content.someProperty).to.equal("someValue", "Property doesnt equal string") + }) + }) + }) + } +} diff --git a/test/validate/ValidatePropertyAnnotatedWithTypeTest.test.ts b/test/validate/ValidatePropertyAnnotatedWithTypeTest.test.ts new file mode 100644 index 0000000..18fb8c4 --- /dev/null +++ b/test/validate/ValidatePropertyAnnotatedWithTypeTest.test.ts @@ -0,0 +1,44 @@ +import { ISerializable, Serializable, serialize, type, validate } from "@js-soft/ts-serval" +import { expect } from "chai" + +export interface IAnotherClass extends ISerializable {} + +@type("AnotherClass") +export class AnotherClass extends Serializable {} + +interface IAClass extends ISerializable { + referenceToAnotherClass?: IAnotherClass +} + +@type("AClass") +class AClass extends Serializable { + @serialize({ type: AnotherClass }) + @validate({ nullable: true }) + public referenceToAnotherClass?: AnotherClass + + public static from(value: IAClass): AClass { + return super.fromT(value, AClass) + } +} + +export class ValidatePropertyAnnotatedWithTypeTest { + public static init(): void { + describe("ValidatePropertyAnnotatedWithType", function () { + it("should parse an object with an optional property without a value", function () { + const parsedValue = AClass.from({ + referenceToAnotherClass: undefined + }) + + expect(parsedValue.referenceToAnotherClass).to.not.exist + }) + + it("should parse an object with an optional property with a value", function () { + const parsedValue = AClass.from({ + referenceToAnotherClass: {} + }) + + expect(parsedValue.referenceToAnotherClass).to.exist + }) + }) + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e3df5d2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "sourceMap": true, + "declaration": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "outDir": "dist", + "strict": false, // Unfortunately strict mode has problems with decorators accessing the this context within getters/setters + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "moduleResolution": "node", + "forceConsistentCasingInFileNames": true, + "downlevelIteration": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "lib": ["es2017", "dom"], + "typeRoots": ["./node_modules/@types"], + "baseUrl": ".", + "paths": { + "@js-soft/ts-serval": ["./src"] + } + }, + "include": ["src/**/*.ts"], + "exclude": ["lib-node", "lib-esm", "lib-test"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..ae936be --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "sourceMap": true, + "declaration": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "outDir": "dist-test", + "strict": false, // Unfortunately strict mode has problems with decorators accessing the this context within getters/setters + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "moduleResolution": "node", + "forceConsistentCasingInFileNames": true, + "downlevelIteration": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "lib": ["es2017", "dom"], + "baseUrl": "./test", + "paths": { + "@js-soft/ts-serval": ["../dist"] + } + }, + "include": ["test/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/ui5.yaml b/ui5.yaml new file mode 100644 index 0000000..b14bded --- /dev/null +++ b/ui5.yaml @@ -0,0 +1,9 @@ +--- +specVersion: "2.0" +type: module +resources: + configuration: + paths: + /resources/ts-serval: ./lib-web/ +metadata: + name: ts-serval diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..3ed2a8b --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,28 @@ +const path = require("path") +const webpack = require("webpack") + +module.exports = { + mode: "development", + node: { + global: false + }, + entry: { + tsserval: "./dist/index" + }, + output: { + path: path.resolve(__dirname, "lib-web"), + filename: "[name].js", + library: "TSServal", + umdNamedDefine: true + }, + resolve: { + extensions: [".js", ".json"], + alias: { + src: path.resolve(__dirname, "tmp-browser/src/") + } + }, + devtool: "source-map", + externals: { + chai: "chai" + } +} diff --git a/webpack.min.config.js b/webpack.min.config.js new file mode 100644 index 0000000..c7f386e --- /dev/null +++ b/webpack.min.config.js @@ -0,0 +1,40 @@ +const path = require("path") +const webpack = require("webpack") +const TerserPlugin = require("terser-webpack-plugin") + +module.exports = { + mode: "production", + node: { + global: false + }, + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + keep_classnames: true, + keep_fnames: true + } + }) + ] + }, + entry: { + "tsserval.min": "./dist/index" + }, + output: { + path: path.resolve(__dirname, "lib-web"), + filename: "[name].js", + library: "TSServal", + umdNamedDefine: true + }, + resolve: { + extensions: [".js", ".json"], + alias: { + src: path.resolve(__dirname, "tmp-browser/src/") + } + }, + devtool: "source-map", + externals: { + chai: "chai" + } +} diff --git a/webpack.test.config.js b/webpack.test.config.js new file mode 100644 index 0000000..be005a7 --- /dev/null +++ b/webpack.test.config.js @@ -0,0 +1,28 @@ +const path = require("path") +const webpack = require("webpack") + +module.exports = { + mode: "development", + node: { + global: false + }, + entry: "./dist-test/index", + output: { + path: path.resolve(__dirname, "lib-web"), + filename: "tsserval.test.js", + library: "TSServalTest", + umdNamedDefine: true + }, + resolve: { + extensions: [".js", ".json"], + alias: { + buffer: "buffer", + src: path.resolve(__dirname, "tmp-browser/src/") + } + }, + devtool: "source-map", + externals: { + chai: "chai", + "@js-soft/ts-serval": "TSServal" + } +}