diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index d3fb901..0000000 --- a/package-lock.json +++ /dev/null @@ -1,11809 +0,0 @@ -{ - "name": "@alien-worlds/api-history-tools", - "version": "0.0.98", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@alien-worlds/api-history-tools", - "version": "0.0.98", - "license": "ISC", - "dependencies": { - "@alien-worlds/api-core": "^0.0.52", - "@eosrio/node-abieos": "^1", - "amqplib": "^0.10.3", - "async": "^3.2.4", - "crypto": "^1.0.1", - "eosjs": "^22.1.0", - "nanoid": "^3.0.0", - "node-fetch": "2.6.6", - "reflect-metadata": "^0.1.13", - "text-encoding": "^0.7.0", - "ts-node": "^10.9.1", - "ws": "^8.12.0" - }, - "devDependencies": { - "@types/jest": "^27.0.3", - "@types/node": "^18.7.14", - "@types/node-fetch": "2.x", - "@typescript-eslint/eslint-plugin": "^5.37.0", - "@typescript-eslint/parser": "^5.37.0", - "eslint": "^8.23.1", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.2.1", - "jest": "^27.4.5", - "prettier": "^2.7.1", - "ts-jest": "^27.1.3", - "typescript": "^4.8.2" - }, - "engines": { - "node": ">=17.3.0 <18.0.0", - "npm": ">=8.3.0 <9.0.0" - } - }, - "node_modules/@acuminous/bitsyntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", - "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", - "license": "MIT", - "dependencies": { - "buffer-more-ints": "~1.0.0", - "debug": "^4.3.4", - "safe-buffer": "~5.1.2" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/@acuminous/bitsyntax/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==", - "license": "MIT" - }, - "node_modules/@alien-worlds/api-core": { - "version": "0.0.52", - "resolved": "https://npm.pkg.github.com/download/@alien-worlds/api-core/0.0.52/4c5e1d202c8c40e3a0969c5eef20192dea6f6abb", - "integrity": "sha512-ANayVbXh3JBawJyLv9FkaBwHNnfbH0E22tVkB6bghNaSSvzPDnNxmXrs+fbejSwvgdcXXSdRDHeyLksbPROtvw==", - "license": "ISC", - "dependencies": { - "@google-cloud/bigquery": "^6.0.3", - "eosjs": "^22.1.0", - "inversify": "^6.0.1", - "mongodb": "4.9.1", - "node-fetch": "2", - "reflect-metadata": "^0.1.13" - }, - "engines": { - "node": ">=17.3.0 <18.0.0", - "npm": ">=8.3.0 <9.0.0" - } - }, - "node_modules/@alien-worlds/api-core/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.0.tgz", - "integrity": "sha512-Gt9jszFJYq7qzXVK4slhc6NzJXnOVmRECWcVjF/T23rNXD9NtWQ0W3qxdg+p9wWIB+VQw3GYV/U2Ha9bRTfs4w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/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, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.0.tgz", - "integrity": "sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.0", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/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, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.0.tgz", - "integrity": "sha512-aGMjYraN0zosCEthoGLdqot1oRsmxVTQRHadsUPz5QM44Zej2PYRz7XiDE7GqnkZnNtLbOuxqoZw42vkU7+XEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.0", - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT", - "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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "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": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.0.tgz", - "integrity": "sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg==", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.0.tgz", - "integrity": "sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.0", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.0.tgz", - "integrity": "sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@eosrio/node-abieos": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@eosrio/node-abieos/-/node-abieos-1.0.6.tgz", - "integrity": "sha512-Y/c0Hi8ylvlHAwUiyI198orbFLfMY2eRtvPWqW4PLudF9yFUXfQwZueDqmitGL2mgTEjXt+WbRGsQc2Oe1C2tA==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "2.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@google-cloud/bigquery": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-6.0.3.tgz", - "integrity": "sha512-BP464228S9dqDCb4dR99h9D8+N498YZi/AZvoOJUaieg2H6qbiYBE1xlYuaMvyV1WEQT/2/yZTCJnCo5WiaY0Q==", - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/common": "^4.0.0", - "@google-cloud/paginator": "^4.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "big.js": "^6.0.0", - "duplexify": "^4.0.0", - "extend": "^3.0.2", - "is": "^3.3.0", - "p-event": "^4.1.0", - "readable-stream": "^4.0.0", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/bigquery/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@google-cloud/bigquery/node_modules/readable-stream": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.2.0.tgz", - "integrity": "sha512-gJrBHsaI3lgBoGMW/jHZsQ/o/TIWiu5ENCJG1BB7fuCKzpFM8GaS2UoBVt9NO+oI+3FcrBNbUkl3ilDe09aY4A==", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@google-cloud/common": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-4.0.3.tgz", - "integrity": "sha512-fUoMo5b8iAKbrYpneIRV3z95AlxVJPrjpevxs4SKoclngWZvTXBSGpNisF5+x5m+oNGve7jfB1e6vNBZBUs7Fw==", - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/projectify": "^3.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^8.0.2", - "retry-request": "^5.0.0", - "teeny-request": "^8.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-4.0.1.tgz", - "integrity": "sha512-6G1ui6bWhNyHjmbYwavdN7mpVPRBtyDg/bfqBTAlwr413On2TnFNfDxc9UhTJctkgoCDgQXEKiRPLPR9USlkbQ==", - "license": "Apache-2.0", - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", - "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", - "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz", - "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/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, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/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, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/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, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "18.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz", - "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==", - "license": "MIT" - }, - "node_modules/@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==", - "license": "MIT" - }, - "node_modules/@types/whatwg-url": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", - "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz", - "integrity": "sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/type-utils": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.41.0.tgz", - "integrity": "sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz", - "integrity": "sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz", - "integrity": "sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.41.0.tgz", - "integrity": "sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz", - "integrity": "sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.41.0.tgz", - "integrity": "sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/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, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz", - "integrity": "sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.41.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/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, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals/node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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, - "license": "MIT", - "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/amqplib": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", - "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", - "license": "MIT", - "dependencies": { - "@acuminous/bitsyntax": "^0.1.2", - "buffer-more-ints": "~1.0.0", - "readable-stream": "1.x >=1.1.9", - "url-parse": "~1.5.10" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "license": "MIT" - }, - "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, - "license": "Python-2.0" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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, - "license": "MIT" - }, - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/big.js": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", - "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==", - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/bigjs" - } - }, - "node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "license": "MIT" - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/bson": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", - "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", - "license": "Apache-2.0", - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "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, - "license": "MIT" - }, - "node_modules/buffer-more-ints": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", - "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001426", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz", - "integrity": "sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ], - "license": "CC-BY-4.0" - }, - "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, - "license": "MIT", - "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/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "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, - "license": "MIT" - }, - "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, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "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==", - "license": "MIT" - }, - "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, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", - "license": "ISC" - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/data-urls/node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "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, - "license": "MIT", - "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, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/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==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/duplexify/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==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true, - "license": "ISC" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "license": "MIT" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "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, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "license": "MIT" - }, - "node_modules/eosjs": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/eosjs/-/eosjs-22.1.0.tgz", - "integrity": "sha512-Ka8KO7akC3RxNdSg/3dkGWuUWUQESTzSUzQljBdVP16UG548vmQoBqSGnZdnjlZyfcab8VOu2iEt+JjyfYc5+A==", - "license": "MIT", - "dependencies": { - "bn.js": "5.2.0", - "elliptic": "6.5.4", - "hash.js": "1.1.7", - "pako": "2.0.3" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "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, - "license": "BSD-2-Clause", - "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/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "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/eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/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, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/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, - "license": "BSD-2-Clause", - "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, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "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, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "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, - "license": "MIT", - "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/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "license": "MIT", - "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.6.0" - } - }, - "node_modules/fast-glob/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, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", - "license": "Apache-2.0" - }, - "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, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "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, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.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, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "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, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "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, - "license": "MIT" - }, - "node_modules/gaxios": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.2.tgz", - "integrity": "sha512-TjtV2AJOZoMQqRYoy5eM8cCQogYwazWNYLQ72QB0kwa6vHHruYkGmhhyrlzbmgNHK1dNnuP2WSH81urfzyN2Og==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/gaxios/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/gcp-metadata": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.0.1.tgz", - "integrity": "sha512-jiRJ+Fk7e8FH68Z6TLaqwea307OktJpDjmYnU7/li6ziwvVvU2RlrCyQo5vkdeP94chm0kcSCOOszvmuaioq3g==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^5.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.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, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-auth-library": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.7.0.tgz", - "integrity": "sha512-1M0NG5VDIvJZEnstHbRdckLZESoJwguinwN8Dhae0j2ZKIQFIV63zxm6Fo6nM4xkgqUr2bbMtV5Dgo+Hy6oo0Q==", - "license": "Apache-2.0", - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^5.0.0", - "gcp-metadata": "^5.0.0", - "gtoken": "^6.1.0", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/google-p12-pem": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", - "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", - "license": "MIT", - "dependencies": { - "node-forge": "^1.3.1" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true, - "license": "ISC" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/gtoken": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", - "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", - "license": "MIT", - "dependencies": { - "gaxios": "^5.0.1", - "google-p12-pem": "^4.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "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, - "license": "Apache-2.0", - "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, - "license": "MIT", - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/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, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/inversify": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.1.tgz", - "integrity": "sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==", - "license": "MIT" - }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "license": "MIT" - }, - "node_modules/is": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "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": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/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, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/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, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsdom/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, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsdom/node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsdom/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/levn/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, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/levn/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, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "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==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/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, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "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==", - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "license": "MIT", - "optional": 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, - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.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, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mongodb": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.9.1.tgz", - "integrity": "sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ==", - "license": "Apache-2.0", - "dependencies": { - "bson": "^4.7.0", - "denque": "^2.1.0", - "mongodb-connection-string-url": "^2.5.3", - "socks": "^2.7.0" - }, - "engines": { - "node": ">=12.9.0" - }, - "optionalDependencies": { - "saslprep": "^1.0.3" - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", - "license": "Apache-2.0", - "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - } - }, - "node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "license": "MIT", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "license": "MIT", - "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": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-addon-api": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", - "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "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, - "license": "MIT", - "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, - "license": "MIT", - "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/optionator/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, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/optionator/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, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "license": "MIT", - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.3.tgz", - "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==", - "license": "(MIT AND Zlib)" - }, - "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, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "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, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" - }, - "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" - } - ], - "license": "MIT" - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT" - }, - "node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "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==", - "license": "Apache-2.0" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "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, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/retry-request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", - "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "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, - "license": "MIT", - "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, - "license": "ISC", - "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" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "license": "MIT", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "license": "MIT", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "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, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "license": "MIT", - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "license": "MIT" - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "license": "MIT" - }, - "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, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/teeny-request": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.2.tgz", - "integrity": "sha512-34pe0a4zASseXZCKdeTiIZqSKA8ETHb1EwItZr01PAR3CLPojeAKgSjzeNS4373gi59hNulyDrPKEbh2zO9sCg==", - "license": "Apache-2.0", - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/teeny-request/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-encoding": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", - "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==", - "license": "(Unlicense OR Apache-2.0)" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@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", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "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/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "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, - "license": "MIT", - "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/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "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, - "license": "MIT", - "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, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "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, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "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, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "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, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "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==", - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@acuminous/bitsyntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", - "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", - "requires": { - "buffer-more-ints": "~1.0.0", - "debug": "^4.3.4", - "safe-buffer": "~5.1.2" - }, - "dependencies": { - "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==" - } - } - }, - "@alien-worlds/api-core": { - "version": "0.0.52", - "resolved": "https://npm.pkg.github.com/download/@alien-worlds/api-core/0.0.52/4c5e1d202c8c40e3a0969c5eef20192dea6f6abb", - "integrity": "sha512-ANayVbXh3JBawJyLv9FkaBwHNnfbH0E22tVkB6bghNaSSvzPDnNxmXrs+fbejSwvgdcXXSdRDHeyLksbPROtvw==", - "requires": { - "@google-cloud/bigquery": "^6.0.3", - "eosjs": "^22.1.0", - "inversify": "^6.0.1", - "mongodb": "4.9.1", - "node-fetch": "2", - "reflect-metadata": "^0.1.13" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.0.tgz", - "integrity": "sha512-Gt9jszFJYq7qzXVK4slhc6NzJXnOVmRECWcVjF/T23rNXD9NtWQ0W3qxdg+p9wWIB+VQw3GYV/U2Ha9bRTfs4w==", - "dev": true - }, - "@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.0.tgz", - "integrity": "sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w==", - "dev": true, - "requires": { - "@babel/types": "^7.20.0", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", - "dev": true, - "requires": { - "@babel/types": "^7.19.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.0.tgz", - "integrity": "sha512-aGMjYraN0zosCEthoGLdqot1oRsmxVTQRHadsUPz5QM44Zej2PYRz7XiDE7GqnkZnNtLbOuxqoZw42vkU7+XEQ==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.0", - "@babel/types": "^7.20.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "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.20.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.0.tgz", - "integrity": "sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.0.tgz", - "integrity": "sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.0", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.0.tgz", - "integrity": "sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eosrio/node-abieos": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@eosrio/node-abieos/-/node-abieos-1.0.6.tgz", - "integrity": "sha512-Y/c0Hi8ylvlHAwUiyI198orbFLfMY2eRtvPWqW4PLudF9yFUXfQwZueDqmitGL2mgTEjXt+WbRGsQc2Oe1C2tA==", - "requires": { - "node-addon-api": "2.0.0" - } - }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@google-cloud/bigquery": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-6.0.3.tgz", - "integrity": "sha512-BP464228S9dqDCb4dR99h9D8+N498YZi/AZvoOJUaieg2H6qbiYBE1xlYuaMvyV1WEQT/2/yZTCJnCo5WiaY0Q==", - "requires": { - "@google-cloud/common": "^4.0.0", - "@google-cloud/paginator": "^4.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "big.js": "^6.0.0", - "duplexify": "^4.0.0", - "extend": "^3.0.2", - "is": "^3.3.0", - "p-event": "^4.1.0", - "readable-stream": "^4.0.0", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "readable-stream": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.2.0.tgz", - "integrity": "sha512-gJrBHsaI3lgBoGMW/jHZsQ/o/TIWiu5ENCJG1BB7fuCKzpFM8GaS2UoBVt9NO+oI+3FcrBNbUkl3ilDe09aY4A==", - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - } - } - } - }, - "@google-cloud/common": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-4.0.3.tgz", - "integrity": "sha512-fUoMo5b8iAKbrYpneIRV3z95AlxVJPrjpevxs4SKoclngWZvTXBSGpNisF5+x5m+oNGve7jfB1e6vNBZBUs7Fw==", - "requires": { - "@google-cloud/projectify": "^3.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^8.0.2", - "retry-request": "^5.0.0", - "teeny-request": "^8.0.0" - } - }, - "@google-cloud/paginator": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-4.0.1.tgz", - "integrity": "sha512-6G1ui6bWhNyHjmbYwavdN7mpVPRBtyDg/bfqBTAlwr413On2TnFNfDxc9UhTJctkgoCDgQXEKiRPLPR9USlkbQ==", - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", - "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==" - }, - "@google-cloud/promisify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", - "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==" - }, - "@humanwhocodes/config-array": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz", - "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "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" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "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" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" - }, - "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/node": { - "version": "18.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz", - "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==" - }, - "@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" - }, - "@types/whatwg-url": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", - "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", - "requires": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz", - "integrity": "sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/type-utils": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.41.0.tgz", - "integrity": "sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz", - "integrity": "sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz", - "integrity": "sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.41.0.tgz", - "integrity": "sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz", - "integrity": "sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.41.0.tgz", - "integrity": "sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "dependencies": { - "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" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz", - "integrity": "sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.41.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "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==" - }, - "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==", - "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" - } - }, - "amqplib": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", - "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", - "requires": { - "@acuminous/bitsyntax": "^0.1.2", - "buffer-more-ints": "~1.0.0", - "readable-stream": "1.x >=1.1.9", - "url-parse": "~1.5.10" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "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" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "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 - }, - "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 - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "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==" - }, - "big.js": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", - "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==" - }, - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "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" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "bson": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", - "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", - "requires": { - "buffer": "^5.6.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "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 - }, - "buffer-more-ints": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", - "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" - }, - "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.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001426", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz", - "integrity": "sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==", - "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" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "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" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "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 - }, - "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" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "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==" - }, - "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" - } - }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "dependencies": { - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - } - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "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 - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "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" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "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==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "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 - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" - }, - "eosjs": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/eosjs/-/eosjs-22.1.0.tgz", - "integrity": "sha512-Ka8KO7akC3RxNdSg/3dkGWuUWUQESTzSUzQljBdVP16UG548vmQoBqSGnZdnjlZyfcab8VOu2iEt+JjyfYc5+A==", - "requires": { - "bn.js": "5.2.0", - "elliptic": "6.5.4", - "hash.js": "1.1.7", - "pako": "2.0.3" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "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": { - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "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" - } - } - } - }, - "eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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" - } - } - } - }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} - }, - "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "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" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "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" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "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-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==" - }, - "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" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "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 - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gaxios": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.2.tgz", - "integrity": "sha512-TjtV2AJOZoMQqRYoy5eM8cCQogYwazWNYLQ72QB0kwa6vHHruYkGmhhyrlzbmgNHK1dNnuP2WSH81urfzyN2Og==", - "requires": { - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "gcp-metadata": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.0.1.tgz", - "integrity": "sha512-jiRJ+Fk7e8FH68Z6TLaqwea307OktJpDjmYnU7/li6ziwvVvU2RlrCyQo5vkdeP94chm0kcSCOOszvmuaioq3g==", - "requires": { - "gaxios": "^5.0.0", - "json-bigint": "^1.0.0" - } - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "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 - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "google-auth-library": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.7.0.tgz", - "integrity": "sha512-1M0NG5VDIvJZEnstHbRdckLZESoJwguinwN8Dhae0j2ZKIQFIV63zxm6Fo6nM4xkgqUr2bbMtV5Dgo+Hy6oo0Q==", - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^5.0.0", - "gcp-metadata": "^5.0.0", - "gtoken": "^6.1.0", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-p12-pem": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", - "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", - "requires": { - "node-forge": "^1.3.1" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "gtoken": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", - "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", - "requires": { - "gaxios": "^5.0.1", - "google-p12-pem": "^4.0.0", - "jws": "^4.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-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 - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "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==" - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "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": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "inversify": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.1.tgz", - "integrity": "sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==" - }, - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, - "is": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-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-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "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==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - } - }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "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-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "js-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": "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" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "@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 - }, - "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" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "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-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "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" - }, - "dependencies": { - "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 - }, - "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" - } - } - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "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" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "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 - }, - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "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==" - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": 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 - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.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 - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mongodb": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.9.1.tgz", - "integrity": "sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ==", - "requires": { - "bson": "^4.7.0", - "denque": "^2.1.0", - "mongodb-connection-string-url": "^2.5.3", - "saslprep": "^1.0.3", - "socks": "^2.7.0" - } - }, - "mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", - "requires": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - }, - "dependencies": { - "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" - }, - "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "requires": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node-addon-api": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", - "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" - }, - "node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "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-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" - } - }, - "nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "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" - }, - "dependencies": { - "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 - }, - "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" - } - } - } - }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "requires": { - "p-timeout": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" - }, - "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" - } - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "requires": { - "p-finally": "^1.0.0" - } - }, - "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 - }, - "pako": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.3.tgz", - "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==" - }, - "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-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "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": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "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-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 - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "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" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "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==" - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "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 - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "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 - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "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" - } - }, - "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.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "retry-request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", - "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", - "requires": { - "debug": "^4.1.1", - "extend": "^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.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "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==" - }, - "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - } - }, - "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-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "optional": true, - "requires": { - "memory-pager": "^1.0.2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "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" - } - }, - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "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 - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" - }, - "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" - } - }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "teeny-request": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.2.tgz", - "integrity": "sha512-34pe0a4zASseXZCKdeTiIZqSKA8ETHb1EwItZr01PAR3CLPojeAKgSjzeNS4373gi59hNulyDrPKEbh2zO9sCg==", - "requires": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-encoding": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", - "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "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" - } - }, - "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@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", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "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" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "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 - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" - }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "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" - } - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - }, - "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 index dc45d15..07b1364 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@alien-worlds/api-history-tools", - "version": "0.0.98", + "version": "0.0.113", "description": "", "packageManager": "yarn@3.2.3", "main": "build/index.js", @@ -35,7 +35,7 @@ "typescript": "^4.8.2" }, "dependencies": { - "@alien-worlds/api-core": "^0.0.87", + "@alien-worlds/api-core": "^0.0.101", "@eosrio/node-abieos": "^1", "amqplib": "^0.10.3", "async": "^3.2.4", diff --git a/src/api/api.config.ts b/src/api/api.config.ts deleted file mode 100644 index 5790e25..0000000 --- a/src/api/api.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type ApiConfig = { - port: number; -} \ No newline at end of file diff --git a/src/api/api.ts b/src/api/api.ts index 37dac22..2a9f49c 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { log, Route } from '@alien-worlds/api-core'; import express, { Express } from 'express'; -import { ApiConfig } from './api.config'; +import { ApiConfig } from './api.types'; export class Api { private app: Express; diff --git a/src/api/api.types.ts b/src/api/api.types.ts new file mode 100644 index 0000000..4a02dfb --- /dev/null +++ b/src/api/api.types.ts @@ -0,0 +1,6 @@ +import { MongoConfig } from '@alien-worlds/api-core'; + +export type ApiConfig = { + port: number; + mongo: MongoConfig; +}; diff --git a/src/api/index.ts b/src/api/index.ts index 36bea22..ce894e8 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,4 @@ export * from './api'; -export * from './api.config'; +export * from './api.types'; export * from './start-api'; export * as ApiEndpoints from './endpoints'; diff --git a/src/api/start-api.ts b/src/api/start-api.ts index 99d8c10..6d8e53c 100644 --- a/src/api/start-api.ts +++ b/src/api/start-api.ts @@ -1,6 +1,6 @@ import { Route } from '@alien-worlds/api-core'; import { Api } from './api'; -import { ApiConfig } from './api.config'; +import { ApiConfig } from './api.types'; export const startApi = async (config: ApiConfig, routes: Route[] = []) => { const api = new Api(config); diff --git a/src/block-range/block-range.config.ts b/src/block-range/block-range.config.ts deleted file mode 100644 index c8998da..0000000 --- a/src/block-range/block-range.config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BroadcastConfig, MongoConfig } from '@alien-worlds/api-core'; -import { AbisServiceConfig } from '../common/abis'; -import { BlockRangeScanConfig } from '../common/block-range-scanner'; -import { BlockReaderConfig } from '../common/blockchain/block-reader'; -import { ContractReaderConfig } from '../common/blockchain/contract-reader'; -import { FeaturedConfig, FeaturedMatchers } from '../common/featured'; -import { WorkersConfig } from '../common/workers'; - -export type BlockRangeConfig = { - broadcast?: BroadcastConfig; - blockReader?: BlockReaderConfig; - contractReader?: ContractReaderConfig; - mongo?: MongoConfig; - scanner?: BlockRangeScanConfig; - featured?: FeaturedConfig; - abis?: AbisServiceConfig; - workers?: WorkersConfig; - mode?: string; - scanKey?: string; - interval?: number; - maxBlockNumber?: number; -}; - -export type BlockRangeAddons = { - matchers?: FeaturedMatchers; -}; diff --git a/src/block-range/block-range.consts.ts b/src/block-range/block-range.consts.ts deleted file mode 100644 index d816a74..0000000 --- a/src/block-range/block-range.consts.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const blockRangeDefaultModeTaskPath = `${__dirname}/tasks/block-range-default-mode.task`; -export const blockRangeReplayModeTaskPath = `${__dirname}/tasks/block-range-replay-mode.task`; -export const blockRangeWorkerLoaderPath = `${__dirname}/block-range.worker-loader`; diff --git a/src/block-range/block-range.types.ts b/src/block-range/block-range.types.ts deleted file mode 100644 index fffcbbe..0000000 --- a/src/block-range/block-range.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { FeaturedContractContent, FeaturedDelta, FeaturedTrace } from '../common/featured'; -import { BlockRangeConfig } from './block-range.config'; - -export type BlockRangeSharedData = { - config: BlockRangeConfig; - featured: { traces: FeaturedTrace[]; deltas: FeaturedDelta[] }; -}; diff --git a/src/block-range/block-range.worker-loader.ts b/src/block-range/block-range.worker-loader.ts deleted file mode 100644 index c8a4cd0..0000000 --- a/src/block-range/block-range.worker-loader.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Broadcast, BroadcastClient, MongoSource } from '@alien-worlds/api-core'; -import { Abis, setupAbis } from '../common/abis'; -import { - BlockReader, - ContractReader, - setupBlockReader, - setupContractReader, -} from '../common/blockchain'; -import { Mode } from '../common/common.enums'; -import { - ProcessorTaskQueue, - setupProcessorTaskQueue, -} from '../common/processor-task-queue'; -import { Worker } from '../common/workers'; -import { DefaultWorkerLoader } from '../common/workers/worker-loader'; -import { InternalBroadcastClientName } from '../internal-broadcast'; -import { BlockRangeSharedData } from './block-range.types'; - -export default class BlockRangeWorkerLoader extends DefaultWorkerLoader { - private mongoSource: MongoSource; - private broadcast: BroadcastClient; - private blockReader: BlockReader; - private contractReader: ContractReader; - private processorQueue: ProcessorTaskQueue; - private abis: Abis; - - public async setup(sharedData: BlockRangeSharedData): Promise { - const { - config: { mongo, broadcast, mode, abis, featured, blockReader, contractReader }, - } = sharedData; - this.mongoSource = await MongoSource.create(mongo); - this.broadcast = await Broadcast.createClient({ - ...broadcast, - clientName: - mode === Mode.Replay - ? InternalBroadcastClientName.BlockRangeReplayModeTask - : InternalBroadcastClientName.BlockRangeDefaultModeTask, - }); - this.abis = await setupAbis(this.mongoSource, abis, featured, true); - this.contractReader = await setupContractReader(contractReader, this.mongoSource); - this.blockReader = await setupBlockReader(blockReader); - this.processorQueue = await setupProcessorTaskQueue(this.mongoSource, true); - } - - public async load(pointer: string, containerPath: string): Promise { - const { mongoSource, broadcast, abis, blockReader, contractReader, processorQueue } = - this; - return super.load( - pointer, - containerPath, - mongoSource, - broadcast, - abis, - blockReader, - contractReader, - processorQueue - ); - } -} diff --git a/src/block-range/index.ts b/src/block-range/index.ts deleted file mode 100644 index 7c9950d..0000000 --- a/src/block-range/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export * from './start-block-range'; -export * from './block-range.config'; -export * from './block-range.consts'; -export * from './block-range.utils'; -export * from './block-range.types'; -export * from './block-range.worker-loader'; -export * from './tasks/block-range-default-mode.task'; -export * from './tasks/block-range-replay-mode.task'; -export * from './tasks/block-range-task.common'; -export * from './service/block-range.default-service'; -export * from './service/block-range.replay-service'; -export * from './service/block-range.service'; -export * from './service/block-range.registry'; diff --git a/src/block-range/service/block-range.default-service.ts b/src/block-range/service/block-range.default-service.ts deleted file mode 100644 index 071460d..0000000 --- a/src/block-range/service/block-range.default-service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { log } from '@alien-worlds/api-core'; -import { Mode } from '../../common/common.enums'; -import { BlockRangeTaskData } from '../../common/common.types'; -import { WorkerPool } from '../../common/workers'; -import { blockRangeDefaultModeTaskPath } from '../block-range.consts'; -import { BlockRangeService } from './block-range.service'; - -export class BlockRangeDefaultService implements BlockRangeService { - public readonly mode = Mode.Default; - - private _isIdle = true; - - constructor(private workerPool: WorkerPool) {} - - public dispose(): void { - this.workerPool.removeWorkers(); - } - - public isIdle() { - return this._isIdle; - } - - public async start(data: BlockRangeTaskData) { - if (this._isIdle && this.workerPool.hasAvailableWorker()) { - this._isIdle = false; - const worker = await this.workerPool.getWorker(blockRangeDefaultModeTaskPath); - worker.onError(error => { - log(error.message); - this.workerPool.releaseWorker(worker.id); - }); - worker.onMessage(async message => { - if (message.isTaskResolved()) { - // run timeout to check if there are more blocks to handle? - } else { - // - } - this._isIdle = true; - this.workerPool.releaseWorker(message.workerId); - }); - worker.run(data); - } - } -} diff --git a/src/block-range/service/block-range.registry.ts b/src/block-range/service/block-range.registry.ts deleted file mode 100644 index c4c41ae..0000000 --- a/src/block-range/service/block-range.registry.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Register (in memory) of currently processed tasks by workers - */ -export class BlockRangeScanRegistry { - private scanByWorkerId: Map = new Map(); - - public add(workerId: number, scanHash: string): boolean { - if (this.scanByWorkerId.has(workerId)) { - return false; - } - - this.scanByWorkerId.set(workerId, scanHash); - - return true; - } - - public has(scanHash: string) { - let result = false; - this.scanByWorkerId.forEach(hash => { - if (hash === scanHash) { - result = true; - } - }); - - return result; - } - - public removeByWorkerId(workerId: number) { - if (this.scanByWorkerId.has(workerId)) { - this.scanByWorkerId.delete(workerId); - } - } - - public removeByHash(scanHash: string) { - let workerId; - this.scanByWorkerId.forEach((hash, id) => { - if (hash === scanHash) { - workerId = id; - } - }); - - if (workerId) { - this.scanByWorkerId.delete(workerId); - } - } -} diff --git a/src/block-range/service/block-range.replay-service.ts b/src/block-range/service/block-range.replay-service.ts deleted file mode 100644 index be9a646..0000000 --- a/src/block-range/service/block-range.replay-service.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { log } from '@alien-worlds/api-core'; -import { Abis } from '../../common/abis'; -import { BlockRangeScanner } from '../../common/block-range-scanner'; -import { Mode } from '../../common/common.enums'; -import { BlockRangeTaskData } from '../../common/common.types'; -import { WorkerMessage, WorkerPool } from '../../common/workers'; -import { blockRangeReplayModeTaskPath } from '../block-range.consts'; -import { BlockRangeScanRegistry } from './block-range.registry'; -import { BlockRangeService } from './block-range.service'; - -export class BlockRangeReplayService implements BlockRangeService { - public readonly mode = Mode.Replay; - - private _isIdle = true; - private _scanKey: string; - private registry: BlockRangeScanRegistry; - - constructor( - private abis: Abis, - private workerPool: WorkerPool, - private scanner: BlockRangeScanner - ) { - workerPool.onWorkerRelease(() => this.next()); - this.registry = new BlockRangeScanRegistry(); - } - - public dispose(): void { - this.workerPool.removeWorkers(); - } - - public isIdle() { - return this._isIdle; - } - - public async next(scanKey?: string) { - const { scanner, abis, workerPool, registry } = this; - - if (this._isIdle === false) { - log( - `Block Range is currently scanning so the received task will be added to the queue.` - ); - return; - } - - if (scanKey?.length > 0 && scanKey !== this._scanKey) { - log(`New key ${scanKey} set for next block range scans.`); - this._scanKey = scanKey; - } - - if (!this._scanKey) { - log(`Scan key not provided, scan cannot be performed.`); - return; - } - - this._isIdle = false; - - // assign tasks to available workers one by one - while ( - workerPool.hasAvailableWorker() && - (await scanner.hasUnscannedBlocks(this._scanKey)) - ) { - const scan = await scanner.getNextScanNode(this._scanKey); - // make sure the scan is available and not being processed by another worker - if (scan && registry.has(scan.hash) === false) { - const { start, end, hash } = scan; - - await abis.getAbis({ startBlock: start, endBlock: end, fetch: true }); - const worker = await workerPool.getWorker(blockRangeReplayModeTaskPath); - log( - ` - Block Range thread #${ - worker.id - } reads ${start.toString()}:${end.toString()} [starting]` - ); - worker.onMessage(async (message: WorkerMessage) => { - log( - ` - Block Range thread #${ - worker.id - } reads ${start.toString()}:${end.toString()} [${ - message.isTaskResolved() ? 'task resolved' : 'task rejected' - }]` - ); - // release the worker and remove scan hash from the registry - registry.removeByWorkerId(message.workerId); - workerPool.releaseWorker(message.workerId); - }); - worker.onError(error => { - log(error); - // release the worker in case of an error and remove scan hash from the registry - registry.removeByWorkerId(worker.id); - workerPool.releaseWorker(worker.id); - }); - - // Add the task to the registry and start the worker - registry.add(worker.id, hash); - worker.run({ - startBlock: start, - endBlock: end, - mode: Mode.Replay, - scanKey: this._scanKey, - }); - } - } - - this._isIdle = true; - - if ((await scanner.hasUnscannedBlocks(this._scanKey)) === false) { - log(`No more block ranges to scan. Well done!`); - } - } -} diff --git a/src/block-range/service/block-range.service.ts b/src/block-range/service/block-range.service.ts deleted file mode 100644 index 70a18a6..0000000 --- a/src/block-range/service/block-range.service.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { setupAbis } from '../../common/abis'; -import { setupBlockRangeScanner } from '../../common/block-range-scanner'; -import { Mode } from '../../common/common.enums'; -import { FeaturedContractContent } from '../../common/featured'; -import { createWorkerPool } from '../../common/workers'; -import { BlockRangeAddons, BlockRangeConfig } from '../block-range.config'; -import { blockRangeWorkerLoaderPath } from '../block-range.consts'; -import { BlockRangeDefaultService } from './block-range.default-service'; -import { BlockRangeReplayService } from './block-range.replay-service'; - -export abstract class BlockRangeService { - private static instance: BlockRangeDefaultService | BlockRangeReplayService; - private static creatorPromise; - - private static async creator( - mode: string, - config: BlockRangeConfig, - addons: BlockRangeAddons - ): Promise { - const featured = new FeaturedContractContent(config.featured, addons.matchers); - if (mode === Mode.Replay) { - const workerPool = await createWorkerPool({ - threadsCount: config.workers.threadsCount, - sharedData: { config, featured: featured.toJson() }, - workerLoaderPath: blockRangeWorkerLoaderPath, - }); - const scanner = await setupBlockRangeScanner(config.mongo, config.scanner); - const abis = await setupAbis(config.mongo, config.abis, config.featured); - - BlockRangeService.instance = new BlockRangeReplayService(abis, workerPool, scanner); - } else { - // In the case of the default/test mode, the block range can have only one worker, - // therefore, regardless of the settings, we create a pool with only one worker - const workerPool = await createWorkerPool({ - threadsCount: 1, - sharedData: { config, featured: featured.toJson() }, - workerLoaderPath: blockRangeWorkerLoaderPath, - }); - - BlockRangeService.instance = new BlockRangeDefaultService(workerPool); - } - // return default block range service if mode === Default or Test - return BlockRangeService.instance; - } - - public mode: Mode; - public abstract isIdle(): boolean; - public abstract dispose(): void; - - public static async getInstance< - ServiceType = BlockRangeDefaultService | BlockRangeReplayService - >( - mode: string, - config: BlockRangeConfig, - addons: BlockRangeAddons - ): Promise { - // if an instance already exists and is of the same type as expected - // return that instance otherwise create a new one - if (BlockRangeService.instance && BlockRangeService.instance.mode === mode) { - return BlockRangeService.instance as ServiceType; - } - - if (BlockRangeService.instance && BlockRangeService.instance.mode !== mode) { - BlockRangeService.creatorPromise = BlockRangeService.creator(mode, config, addons); - } else if (!BlockRangeService.instance && !BlockRangeService.creatorPromise) { - BlockRangeService.creatorPromise = BlockRangeService.creator(mode, config, addons); - } - - return BlockRangeService.creatorPromise; - } -} diff --git a/src/block-range/service/index.ts b/src/block-range/service/index.ts deleted file mode 100644 index ad48718..0000000 --- a/src/block-range/service/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './block-range.default-service'; -export * from './block-range.replay-service'; -export * from './block-range.service'; -export * from './block-range.registry'; diff --git a/src/block-range/start-block-range.ts b/src/block-range/start-block-range.ts deleted file mode 100644 index 9d10a44..0000000 --- a/src/block-range/start-block-range.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - InternalBroadcastChannel, - InternalBroadcastClientName, - InternalBroadcastMessageName, -} from './../internal-broadcast/internal-broadcast.enums'; -import { Broadcast, log } from '@alien-worlds/api-core'; -import { Mode } from '../common/common.enums'; -import { BlockRangeAddons, BlockRangeConfig } from './block-range.config'; -import { InternalBroadcastMessage } from '../internal-broadcast/internal-broadcast.message'; -import { BlockRangeBroadcastMessages } from '../internal-broadcast/messages/block-range-broadcast.messages'; -import { BlockRangeTaskData } from '../common/common.types'; -import { logTaskInfo } from './block-range.utils'; -import { - BlockRangeReplayService, - BlockRangeDefaultService, - BlockRangeService, -} from './service'; - -/** - * - * @param broadcastMessageMapper - * @param config - * @returns - */ -export const startBlockRange = async ( - config: BlockRangeConfig, - addons: BlockRangeAddons = {} -) => { - log(`Block Range ... [starting]`); - - const { mode, scanKey } = config; - - // If the following options are given, the process will continue replay mode - // "standalone" mode - regardless of whether the filler is running or not - // The interval will persist in case of new block range - if (scanKey && mode === Mode.Replay) { - log(`Block Range started in "standalone" replay mode`); - ( - await BlockRangeService.getInstance(mode, config, addons) - ).next(scanKey); - } else { - const broadcast = await Broadcast.createClient({ - ...config.broadcast, - clientName: InternalBroadcastClientName.BlockRange, - }); - - broadcast.onMessage( - InternalBroadcastChannel.Processor, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - async (message: InternalBroadcastMessage) => { - // - } - ); - // Runs the process in "listening mode" for tasks sent from the filler - log(`Block Range started in "listening" mode`); - broadcast.onMessage( - InternalBroadcastChannel.BlockRange, - async (message: InternalBroadcastMessage) => { - const { - content: { data, name }, - } = message; - if (name === InternalBroadcastMessageName.BlockRangeTask) { - // - logTaskInfo(message); - if (data.mode === Mode.Replay) { - // start replay mode - ( - await BlockRangeService.getInstance( - data.mode, - config, - addons - ) - ).next(data.scanKey); - } else if (data.mode === Mode.Default) { - // start default mode - ( - await BlockRangeService.getInstance( - data.mode, - config, - addons - ) - ).start(data); - } else { - log(`Unknown mode ${data.mode}.`); - } - } - } - ); - await broadcast.connect(); - // Everything is ready, notify the filler that the process is ready to work - broadcast.sendMessage(BlockRangeBroadcastMessages.createBlockRangeReadyMessage()); - } - - log(`Block Range ... [ready]`); -}; diff --git a/src/block-range/tasks/block-range-default-mode.task.ts b/src/block-range/tasks/block-range-default-mode.task.ts deleted file mode 100644 index db4e71f..0000000 --- a/src/block-range/tasks/block-range-default-mode.task.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { log, MongoSource, BroadcastClient, parseToBigInt } from '@alien-worlds/api-core'; -import { Mode } from './../../common/common.enums'; -import { setupBlockState } from '../../common/block-state'; -import { BlockReader, ReceivedBlock } from '../../common/blockchain/block-reader'; -import { Worker } from '../../common/workers/worker'; -import { - createDeltaProcessorTasks, - createActionProcessorTasks, -} from './block-range-task.common'; -import { ProcessorTaskQueue } from '../../common/processor-task-queue'; -import { BlockRangeTaskData } from '../../common/common.types'; -import { ProcessorQueueBroadcastMessages } from '../../internal-broadcast/messages/processor-queue-broadcast.messages'; -import { ContractReader } from '../../common/blockchain/contract-reader'; -import { BlockRangeSharedData } from '../block-range.types'; -import { Abis } from '../../common/abis'; - -export default class BlockRangeDefaultModeTask extends Worker { - constructor( - protected mongoSource: MongoSource, - protected broadcast: BroadcastClient, - protected abis: Abis, - protected blockReader: BlockReader, - protected contractReader: ContractReader, - protected processorQueue: ProcessorTaskQueue - ) { - super(); - } - - public async run( - data: BlockRangeTaskData, - sharedData: BlockRangeSharedData - ): Promise { - const { mongoSource, broadcast, abis, blockReader, contractReader, processorQueue } = - this; - const { startBlock, endBlock } = data; - const { config, featured } = sharedData; - const { - blockReader: { shouldFetchDeltas, shouldFetchTraces }, - } = config; - const maxBlockNumber = config.maxBlockNumber || 0xffffffff; - const blockState = await setupBlockState(mongoSource); - const state = await blockState.getState(); - const currentBlock = - state.blockNumber && state.blockNumber > startBlock - ? state.blockNumber - : startBlock; - - blockReader.onReceivedBlock(async (receivedBlock: ReceivedBlock) => { - const { - traces, - deltas, - block: { timestamp }, - thisBlock: { blockNumber }, - } = receivedBlock; - - const state = await blockState.getState(); - const isMicroFork = blockNumber <= state.blockNumber; - const [actionProcessorTasks, deltaProcessorTasks] = await Promise.all([ - createActionProcessorTasks( - contractReader, - abis, - Mode.Default, - traces, - featured.traces, - blockNumber, - timestamp, - isMicroFork - ), - createDeltaProcessorTasks( - contractReader, - abis, - Mode.Default, - deltas, - featured.deltas, - blockNumber, - timestamp, - isMicroFork - ), - ]); - - const tasks = [...actionProcessorTasks, ...deltaProcessorTasks]; - - // mark this block as a new state only if its index is not lower than the current state - if (blockNumber > state.blockNumber) { - blockState.newState(blockNumber); - } - - if (tasks.length > 0) { - log( - `Block #${blockNumber} contains ${actionProcessorTasks.length} actions and ${deltaProcessorTasks.length} deltas to process (${tasks.length} tasks in total).` - ); - processorQueue.addTasks(tasks); - } else { - log( - `The block (${blockNumber}) does not contain actions and deltas that could be processed.` - ); - } - broadcast.sendMessage(ProcessorQueueBroadcastMessages.createUpdateMessage()); - }); - - blockReader.onError(error => { - this.reject(error); - }); - - blockReader.onComplete(async () => { - this.resolve({ startBlock: currentBlock, endBlock }); - }); - - // start reading blockchain - blockReader.readBlocks(currentBlock, endBlock || parseToBigInt(maxBlockNumber), { - shouldFetchDeltas, - shouldFetchTraces, - }); - } -} diff --git a/src/block-range/tasks/block-range-replay-mode.task.ts b/src/block-range/tasks/block-range-replay-mode.task.ts deleted file mode 100644 index 26e9e5e..0000000 --- a/src/block-range/tasks/block-range-replay-mode.task.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { BroadcastClient, log, MongoSource } from '@alien-worlds/api-core'; -import { BlockReader, ReceivedBlock } from '../../common/blockchain/block-reader'; -import { Worker } from '../../common/workers/worker'; -import { - createDeltaProcessorTasks, - createActionProcessorTasks, -} from './block-range-task.common'; -import { Mode } from '../../common/common.enums'; -import { ProcessorTaskQueue } from '../../common/processor-task-queue'; -import { BlockRangeTaskData } from '../../common/common.types'; -import { setupBlockRangeScanner } from '../../common/block-range-scanner'; -import { ContractReader } from '../../common/blockchain/contract-reader'; -import { BlockRangeSharedData } from '../block-range.types'; -import { ProcessorQueueBroadcastMessages } from '../../internal-broadcast'; -import { Abis } from '../../common/abis'; - -export default class BlockRangeReplayModeTask extends Worker { - constructor( - protected mongoSource: MongoSource, - protected broadcast: BroadcastClient, - protected abis: Abis, - protected blockReader: BlockReader, - protected contractReader: ContractReader, - protected processorQueue: ProcessorTaskQueue - ) { - super(); - } - - public async run( - data: BlockRangeTaskData, - sharedData: BlockRangeSharedData - ): Promise { - const { startBlock, endBlock, scanKey, mode } = data; - const { mongoSource, broadcast, abis, blockReader, contractReader, processorQueue } = - this; - const { config, featured } = sharedData; - const { - blockReader: { shouldFetchDeltas, shouldFetchTraces }, - } = config; - - const scanner = await setupBlockRangeScanner(mongoSource, config.scanner); - - blockReader.onReceivedBlock(async (receivedBlock: ReceivedBlock) => { - const { - traces, - deltas, - block: { timestamp }, - thisBlock: { blockNumber }, - } = receivedBlock; - - const [actionProcessorTasks, deltaProcessorTasks] = await Promise.all([ - createActionProcessorTasks( - contractReader, - abis, - Mode.Replay, - traces, - featured.traces, - blockNumber, - timestamp, - false - ), - createDeltaProcessorTasks( - contractReader, - abis, - Mode.Replay, - deltas, - featured.deltas, - blockNumber, - timestamp, - false - ), - ]); - const tasks = [...actionProcessorTasks, ...deltaProcessorTasks]; - - if (tasks.length > 0) { - log( - `Block #${blockNumber} contains ${actionProcessorTasks.length} actions and ${deltaProcessorTasks.length} deltas to process (${tasks.length} tasks in total).` - ); - processorQueue.addTasks(tasks); - } else { - log( - `The block (${blockNumber}) does not contain actions and deltas that could be processed.` - ); - } - - broadcast.sendMessage(ProcessorQueueBroadcastMessages.createUpdateMessage()); - - // - await scanner.updateScanProgress(scanKey, blockNumber); - }); - - blockReader.onError(error => { - this.reject(error); - }); - - blockReader.onComplete(async () => { - this.resolve({ startBlock, endBlock, scanKey, mode }); - }); - - blockReader.readBlocks(startBlock, endBlock, { - shouldFetchDeltas, - shouldFetchTraces, - }); - } -} diff --git a/src/block-range/tasks/block-range-task.common.ts b/src/block-range/tasks/block-range-task.common.ts deleted file mode 100644 index 1159699..0000000 --- a/src/block-range/tasks/block-range-task.common.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { log } from '@alien-worlds/api-core'; -import { Abis } from '../../common/abis'; -import { Delta, Trace } from '../../common/blockchain/block-content'; -import { ContractReader } from '../../common/blockchain/contract-reader'; -import { isSetAbiAction } from '../../common/common.utils'; -import { - FeaturedDelta, - FeaturedDeltas, - FeaturedTrace, - FeaturedTraces, -} from '../../common/featured'; -import { ProcessorTask } from '../../common/processor-task-queue'; -import { extractAllocationFromDeltaRow } from '../block-range.utils'; - -/** - * - * @param trace - * @param broadcast - * @param featured - */ -export const createActionProcessorTasks = async ( - contractReader: ContractReader, - abis: Abis, - mode: string, - traces: Trace[], - featuredTraces: FeaturedTrace[], - blockNumber: bigint, - blockTimestamp: Date, - isMicroFork: boolean, -): Promise => { - const list: ProcessorTask[] = []; - const featured = new FeaturedTraces(featuredTraces); - - for (const trace of traces) { - const { id, actionTraces, shipTraceMessageName } = trace; - - for (const actionTrace of actionTraces) { - const { - act: { account, name }, - } = actionTrace; - - const matchedTraces = await featured.get({ - shipTraceMessageName, - action: name, - contract: account, - }); - - if (matchedTraces.length > 0) { - try { - // If the block in which the contract was created cannot be found or - // its index is higher than the current block number, skip it, - // the contract did not exist at that time - const initBlockNumber = await contractReader.getInitialBlockNumber(account); - if (initBlockNumber === -1n || initBlockNumber > blockNumber) { - continue; - } - - // get ABI from the database and if it does not exist, try to fetch it - const abi = await abis.getAbi(blockNumber, account, true); - if (!abi && isSetAbiAction(account, name) === false) { - log( - `Action-trace {block_number: ${blockNumber}, account: ${account}, name: ${name}}: no ABI was found. This can be a problem in reading the content.` - ); - } - list.push( - ProcessorTask.createActionProcessorTask( - abi ? abi.hex : '', - mode, - shipTraceMessageName, - id, - actionTrace, - blockNumber, - blockTimestamp, - isMicroFork - ) - ); - } catch (error) { - log(`Action-trace not handled`, error); - } - } - } - } - return list; -}; - -/** - * - * @param delta - * @param broadcast - * @param featuredDeltas - */ -export const createDeltaProcessorTasks = async ( - contractReader: ContractReader, - abis: Abis, - mode: string, - deltas: Delta[], - featuredDeltas: FeaturedDelta[], - blockNumber: bigint, - blockTimestamp: Date, - isMicroFork: boolean -): Promise => { - const list: ProcessorTask[] = []; - const featured = new FeaturedDeltas(featuredDeltas); - - for (const delta of deltas) { - const { name, shipDeltaMessageName } = delta; - const allocations = delta.rows.map(row => extractAllocationFromDeltaRow(row.data)); - - for (let i = 0; i < delta.rows.length; i++) { - const row = delta.rows[i]; - const allocation = allocations[i]; - - if (!allocation) { - // contract allocation cannot be extracted - // The contract may not contain tables or may be corrupted - continue; - } - - const { code, scope, table } = allocation; - const matchedDeltas = await featured.get({ - shipDeltaMessageName, - name, - code, - scope, - table, - }); - - if (matchedDeltas.length > 0) { - try { - // If the block in which the contract was created cannot be found or - // its index is higher than the current block number, skip it, - // the contract did not exist at that time - const initBlockNumber = await contractReader.getInitialBlockNumber(code); - if (initBlockNumber === -1n || initBlockNumber > blockNumber) { - continue; - } - - // get ABI from the database and if it does not exist, try to fetch it - const abi = await abis.getAbi(blockNumber, code, true); - if (!abi) { - log( - `Delta {block_number: ${blockNumber}, code: ${code}, scope: ${scope}, table: ${table}}: no ABI was found. This can be a problem in reading the content.` - ); - } - list.push( - ProcessorTask.createDeltaProcessorTask( - abi ? abi.hex : '', - mode, - shipDeltaMessageName, - name, - code, - scope, - table, - blockNumber, - blockTimestamp, - row, - isMicroFork, - ) - ); - } catch (error) { - log(`Delta (table row) not handled`, error); - } - } - } - } - - return list; -}; diff --git a/src/filler/filler.errors.ts b/src/bootstrap/bootstrap.errors.ts similarity index 100% rename from src/filler/filler.errors.ts rename to src/bootstrap/bootstrap.errors.ts diff --git a/src/bootstrap/bootstrap.types.ts b/src/bootstrap/bootstrap.types.ts new file mode 100644 index 0000000..b930c58 --- /dev/null +++ b/src/bootstrap/bootstrap.types.ts @@ -0,0 +1,35 @@ +import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; +import { AbisServiceConfig } from '../common/abis'; +import { BlockRangeScanConfig } from '../reader/block-range-scanner'; +import { BlockchainConfig, ContractReaderConfig } from '../common/blockchain'; +import { FeaturedConfig } from '../common/featured'; +import { Mode } from '../common'; + +export type BootstrapConfig = { + broadcast: BroadcastConfig; + blockchain: BlockchainConfig; + contractReader: ContractReaderConfig; + scanner: BlockRangeScanConfig; + mongo: MongoConfig; + startBlock?: bigint; + endBlock?: bigint; + startFromHead?: boolean; + mode: string; + featured: FeaturedConfig; + abis: AbisServiceConfig; + maxBlockNumber?: number; +}; + +export type BootstrapCommandOptions = { + scanKey: string; + startBlock: string; + endBlock: string; + mode: Mode; +}; + +export type BlockRangeData = { + startBlock?: bigint; + endBlock?: bigint; + mode: string; + scanKey?: string; +}; diff --git a/src/filler/filler.utils.ts b/src/bootstrap/bootstrap.utils.ts similarity index 53% rename from src/filler/filler.utils.ts rename to src/bootstrap/bootstrap.utils.ts index 5bc9a71..3af9f4a 100644 --- a/src/filler/filler.utils.ts +++ b/src/bootstrap/bootstrap.utils.ts @@ -1,31 +1,30 @@ import { log, parseToBigInt } from '@alien-worlds/api-core'; -import { BlockRangeScanner } from '../common/block-range-scanner'; +import { BlockRangeScanner } from '../reader/block-range-scanner'; import { BlockState } from '../common/block-state'; -import { fetchBlockchainInfo, getHeadBlockNumber, getLastIrreversibleBlockNumber } from '../common/blockchain'; import { Mode } from '../common/common.enums'; import { UnknownModeError } from '../common/common.errors'; -import { BlockRangeTaskData } from '../common/common.types'; -import { FillerConfig } from './filler.config'; +import { BlockRangeData, BootstrapConfig } from './bootstrap.types'; import { StartBlockHigherThanEndBlockError, UndefinedStartBlockError, EndBlockOutOfRangeError, -} from './filler.errors'; +} from './bootstrap.errors'; +import { Blockchain } from '../common'; export const createBlockRangeTaskInput = ( blockState: BlockState, scanner: BlockRangeScanner, - config: FillerConfig + config: BootstrapConfig ) => { const { mode } = config; if (mode === Mode.Default) { - return prepareDefaultModeInput(blockState, config); + return createDefaultModeBlockRange(blockState, config); } else if (mode === Mode.Replay) { // - return prepareReplayModeInput(scanner, config); + return createReplayModeBlockRange(scanner, config); } else if (mode === Mode.Test) { // - return prepareTestModeInput(config); + return createTestModeBlockRange(config); } else { // throw new UnknownModeError(mode); @@ -35,56 +34,67 @@ export const createBlockRangeTaskInput = ( /** * * @param {Broadcast} broadcast - * @param {FillerConfig} config + * @param {BootstrapConfig} config */ -export const prepareDefaultModeInput = async ( +export const createDefaultModeBlockRange = async ( blockState: BlockState, - config: FillerConfig -): Promise => { + config: BootstrapConfig +): Promise => { const { startBlock, endBlock, mode, scanner: { scanKey }, - blockchain: { chainId, endpoint }, startFromHead, + maxBlockNumber, } = config; - const blockchainInfo = await fetchBlockchainInfo(endpoint, chainId); - const lastIrreversibleBlock = parseToBigInt(blockchainInfo.last_irreversible_block_num); - const headBlock = parseToBigInt(blockchainInfo.head_block_num); - const currentBlockNumber = await blockState.getBlockNumber(); + const blockchain = await Blockchain.create(config.blockchain); + const lastIrreversibleBlock = await blockchain.getLastIrreversibleBlockNumber(); + const headBlock = await blockchain.getHeadBlockNumber(); + const { content: currentBlockNumber } = await blockState.getBlockNumber(); + + log(` Current head block number: ${headBlock.toString()}`); + log(` Current last irreversible block number: ${lastIrreversibleBlock.toString()}`); + log(` Current state block number: ${currentBlockNumber.toString()}`); let highEdge: bigint; let lowEdge: bigint; - if (typeof startBlock !== 'bigint' && currentBlockNumber > 0n) { - lowEdge = currentBlockNumber; - log(` Using current state block number ${lowEdge.toString()}`); - } else if (typeof startBlock !== 'bigint' && currentBlockNumber < 0n) { - if (startFromHead) { + if (currentBlockNumber > 0n) { + lowEdge = currentBlockNumber + 1n; + log(` Using the current state block number (+1) ${lowEdge.toString()} as a start block`); + } else { + if (startBlock < 0n) { + if (startFromHead) { + lowEdge = headBlock + startBlock; + log( + ` Using the offset (${startBlock.toString()}) from the head block number as a start block` + ); + } else { + lowEdge = lastIrreversibleBlock + startBlock; + log( + ` Using the offset (${startBlock.toString()}) from the last irreversable block number as a start block` + ); + } + } else if (startBlock > 0n) { + lowEdge = startBlock; + } else if (startFromHead) { lowEdge = headBlock; - log(` Using head block number ${lowEdge.toString()}`); + log(` Using the head block number ${lowEdge.toString()} as a start block`); } else { lowEdge = lastIrreversibleBlock; - log(` Using last irreversable block number ${lowEdge.toString()}`); - } - } else if (startBlock < 0n) { - if (startFromHead) { - lowEdge = headBlock + startBlock; - log(` Using offset (${startBlock.toString()}) from the head block number`); - } else { - lowEdge = lastIrreversibleBlock + startBlock; log( - ` Using offset (${startBlock.toString()}) from the last irreversable block number` + ` Using the last irreversable block number ${lowEdge.toString()} as a start block` ); } - } else { - lowEdge = startBlock; } if (typeof endBlock !== 'bigint') { - highEdge = parseToBigInt(0xffffffff); + highEdge = parseToBigInt(maxBlockNumber || 0xffffffff); } else { + log( + ` Using the end block number specified in the variables: ${endBlock.toString()} (exclusive) as an end block` + ); highEdge = endBlock; } @@ -98,20 +108,21 @@ export const prepareDefaultModeInput = async ( /** * * @param {Broadcast} broadcast - * @param {FillerConfig} config + * @param {BootstrapConfig} config */ -export const prepareTestModeInput = async (config: FillerConfig) => { +export const createTestModeBlockRange = async ( + config: BootstrapConfig +): Promise => { const { startBlock, mode, scanner: { scanKey }, - blockchain: { chainId, endpoint }, startFromHead, } = config; - const blockchainInfo = await fetchBlockchainInfo(endpoint, chainId); - const lastIrreversibleBlock = parseToBigInt(blockchainInfo.last_irreversible_block_num); - const headBlock = parseToBigInt(blockchainInfo.head_block_num); + const blockchain = await Blockchain.create(config.blockchain); + const lastIrreversibleBlock = await blockchain.getLastIrreversibleBlockNumber(); + const headBlock = await blockchain.getHeadBlockNumber(); let highEdge: bigint; let lowEdge: bigint; @@ -130,14 +141,13 @@ export const prepareTestModeInput = async (config: FillerConfig) => { /** * * @param {Broadcast} broadcast - * @param {FillerConfig} config + * @param {BootstrapConfig} config */ -export const prepareReplayModeInput = async ( +export const createReplayModeBlockRange = async ( scanner: BlockRangeScanner, - config: FillerConfig -) => { + config: BootstrapConfig +): Promise => { const { - blockchain: { chainId, endpoint }, scanner: { scanKey }, startBlock, endBlock, @@ -147,7 +157,8 @@ export const prepareReplayModeInput = async ( const lowEdge = startBlock; let highEdge = endBlock; - const lastIrreversibleBlock = await getLastIrreversibleBlockNumber(endpoint, chainId); + const blockchain = await Blockchain.create(config.blockchain); + const lastIrreversibleBlock = await blockchain.getLastIrreversibleBlockNumber(); if (typeof lowEdge !== 'bigint') { throw new UndefinedStartBlockError(); diff --git a/src/bootstrap/index.ts b/src/bootstrap/index.ts new file mode 100644 index 0000000..96c62e6 --- /dev/null +++ b/src/bootstrap/index.ts @@ -0,0 +1,4 @@ +export * from './bootstrap.types'; +export * from './bootstrap.errors'; +export * from './bootstrap.utils'; +export * from './start-bootstrap'; diff --git a/src/bootstrap/start-bootstrap.ts b/src/bootstrap/start-bootstrap.ts new file mode 100644 index 0000000..24216f5 --- /dev/null +++ b/src/bootstrap/start-bootstrap.ts @@ -0,0 +1,89 @@ +import { + ReaderBroadcastMessage, + ReaderBroadcastMessageData, +} from '../broadcast/messages/reader-broadcast.message'; +import { + createDefaultModeBlockRange, + createReplayModeBlockRange, + createTestModeBlockRange, +} from './bootstrap.utils'; +import { Broadcast, log, MongoSource } from '@alien-worlds/api-core'; +import { BootstrapConfig } from './bootstrap.types'; +import { NoAbisError } from './bootstrap.errors'; +import { + InternalBroadcastChannel, + InternalBroadcastClientName, + InternalBroadcastMessageName, +} from '../broadcast/internal-broadcast.enums'; +import { FeaturedContractContent } from '../common/featured'; +import { Mode } from '../common/common.enums'; +import { InternalBroadcastMessage } from '../broadcast'; +import { Abis, BlockRangeScanner, BlockState, ContractReader } from '../common'; + +/** + * + * @param broadcastMessageMapper + * @param config + * @returns + */ +export const startBootstrap = async (config: BootstrapConfig) => { + const { mode } = config; + log(`Bootstrap "${mode}" mode ... [starting]`); + + const broadcast = await Broadcast.createClient({ + ...config.broadcast, + clientName: InternalBroadcastClientName.Bootstrap, + }); + const mongo = await MongoSource.create(config.mongo); + const contractReader = await ContractReader.create(config.contractReader, mongo); + const abis = await Abis.create(mongo, config.abis, config.featured); + const scanner = await BlockRangeScanner.create(mongo, config.scanner); + const featured = new FeaturedContractContent(config.featured); + const blockState = await BlockState.create(mongo); + let blockRange: ReaderBroadcastMessageData; + + // fetch latest abis to make sure that the blockchain data will be correctly deserialized + log(` * Fetch featured contracts details ... [starting]`); + await contractReader.readContracts(featured.listContracts()); + log(` * Fetch featured contracts details ... [done]`); + + // fetch latest abis to make sure that the blockchain data will be correctly deserialized + log(` * Fetch abis ... [starting]`); + const abisCount = (await abis.fetchAbis()).length; + log(` * Fetch abis ... [done]`); + + if (abisCount === 0) { + throw new NoAbisError(); + } + + if (config.mode === Mode.Replay) { + blockRange = await createReplayModeBlockRange(scanner, config); + } + + broadcast.onMessage( + InternalBroadcastChannel.Bootstrap, + async (message: InternalBroadcastMessage) => { + if (message.content.name === InternalBroadcastMessageName.DefaultModeReaderReady) { + if (config.mode === Mode.Default) { + blockRange = await createDefaultModeBlockRange(blockState, config); + broadcast.sendMessage(ReaderBroadcastMessage.newDefaultModeTask(blockRange)); + } + + if (config.mode === Mode.Test) { + blockRange = await createTestModeBlockRange(config); + broadcast.sendMessage(ReaderBroadcastMessage.newDefaultModeTask(blockRange)); + } + } else if ( + message.content.name === InternalBroadcastMessageName.ReplayModeReaderReady + ) { + broadcast.sendMessage(ReaderBroadcastMessage.newReplayModeTask(blockRange)); + } else { + // + } + } + ); + + broadcast.connect(); + + log(`Bootstrap ${mode} mode ... [ready]`); +}; diff --git a/src/broadcast/index.ts b/src/broadcast/index.ts new file mode 100644 index 0000000..5bf2f7c --- /dev/null +++ b/src/broadcast/index.ts @@ -0,0 +1,4 @@ +export * from './internal-broadcast.enums'; +export * from './internal-broadcast.message'; +export * from './messages'; + diff --git a/src/broadcast/internal-broadcast.enums.ts b/src/broadcast/internal-broadcast.enums.ts new file mode 100644 index 0000000..9773780 --- /dev/null +++ b/src/broadcast/internal-broadcast.enums.ts @@ -0,0 +1,26 @@ +export enum InternalBroadcastChannel { + Bootstrap = 'bootstrap', + DefaultModeReader = 'default-mode-reader', + ReplayModeReader = 'replay-mode-reader', + Filter = 'filter', + Processor = 'processor', + ExternalBroadcast = 'external-broadcast', +} + +export enum InternalBroadcastClientName { + Bootstrap = 'bootstrap', + Filter = 'filter', + Reader = 'reader', + Processor = 'processor', + ExternalBroadcast = 'external-broadcast', +} + +export enum InternalBroadcastMessageName { + FilterReady = 'filter-ready', + FilterRefresh = 'filter-refresh', + DefaultModeReaderReady = 'default-mode-reader-ready', + ReplayModeReaderReady = 'replay-mode-reader-ready', + ReaderTask = 'reader-task', + ProcessorReady = 'processor-ready', + ProcessorRefresh = 'processor-refresh', +} diff --git a/src/internal-broadcast/internal-broadcast.message.ts b/src/broadcast/internal-broadcast.message.ts similarity index 100% rename from src/internal-broadcast/internal-broadcast.message.ts rename to src/broadcast/internal-broadcast.message.ts diff --git a/src/broadcast/messages/filter-broadcast.message.ts b/src/broadcast/messages/filter-broadcast.message.ts new file mode 100644 index 0000000..73e689d --- /dev/null +++ b/src/broadcast/messages/filter-broadcast.message.ts @@ -0,0 +1,26 @@ +import { BroadcastTcpMessageType } from '@alien-worlds/api-core'; +import { + InternalBroadcastChannel, + InternalBroadcastMessageName, +} from '../internal-broadcast.enums'; + +/** + * Message content + */ +export class FilterBroadcastMessage { + public static ready() { + return { + channel: InternalBroadcastChannel.Bootstrap, + name: InternalBroadcastMessageName.FilterReady, + type: BroadcastTcpMessageType.Data, + }; + } + + public static refresh() { + return { + channel: InternalBroadcastChannel.Filter, + name: InternalBroadcastMessageName.FilterRefresh, + type: BroadcastTcpMessageType.Data, + }; + } +} diff --git a/src/broadcast/messages/index.ts b/src/broadcast/messages/index.ts new file mode 100644 index 0000000..cf4aadc --- /dev/null +++ b/src/broadcast/messages/index.ts @@ -0,0 +1,3 @@ +export * from './reader-broadcast.message'; +export * from './filter-broadcast.message'; +export * from './processor-broadcast.message'; diff --git a/src/internal-broadcast/messages/processor-broadcast.messages.ts b/src/broadcast/messages/processor-broadcast.message.ts similarity index 58% rename from src/internal-broadcast/messages/processor-broadcast.messages.ts rename to src/broadcast/messages/processor-broadcast.message.ts index 7448b09..5c25a59 100644 --- a/src/internal-broadcast/messages/processor-broadcast.messages.ts +++ b/src/broadcast/messages/processor-broadcast.message.ts @@ -7,12 +7,20 @@ import { /** * Message content */ -export class ProcessorBroadcastMessages { - public static createProcessorReadyMessage() { +export class ProcessorBroadcastMessage { + public static ready() { return { channel: InternalBroadcastChannel.Processor, name: InternalBroadcastMessageName.ProcessorReady, type: BroadcastTcpMessageType.Data, }; } + + public static refresh() { + return { + channel: InternalBroadcastChannel.Processor, + name: InternalBroadcastMessageName.ProcessorRefresh, + type: BroadcastTcpMessageType.Data, + }; + } } diff --git a/src/broadcast/messages/reader-broadcast.message.ts b/src/broadcast/messages/reader-broadcast.message.ts new file mode 100644 index 0000000..58a83ac --- /dev/null +++ b/src/broadcast/messages/reader-broadcast.message.ts @@ -0,0 +1,54 @@ +import { BroadcastTcpMessageType } from '@alien-worlds/api-core'; +import { Mode } from '../../common/common.enums'; +import { + InternalBroadcastChannel, + InternalBroadcastMessageName, +} from '../internal-broadcast.enums'; + +export type ReaderBroadcastMessageData = { + startBlock?: bigint; + endBlock?: bigint; + mode: string; + scanKey?: string; +}; + +/** + * Message content + */ +export class ReaderBroadcastMessage { + public static newReplayModeTask(data: ReaderBroadcastMessageData) { + data.mode = Mode.Replay; + return { + channel: InternalBroadcastChannel.ReplayModeReader, + name: InternalBroadcastMessageName.ReaderTask, + type: BroadcastTcpMessageType.Data, + data, + }; + } + + public static newDefaultModeTask(data: ReaderBroadcastMessageData) { + data.mode = Mode.Default; + return { + channel: InternalBroadcastChannel.DefaultModeReader, + name: InternalBroadcastMessageName.ReaderTask, + type: BroadcastTcpMessageType.Data, + data, + }; + } + + public static defaultModeReady() { + return { + channel: InternalBroadcastChannel.Bootstrap, + name: InternalBroadcastMessageName.DefaultModeReaderReady, + type: BroadcastTcpMessageType.Data, + }; + } + + public static replayModeReady() { + return { + channel: InternalBroadcastChannel.Bootstrap, + name: InternalBroadcastMessageName.ReplayModeReaderReady, + type: BroadcastTcpMessageType.Data, + }; + } +} diff --git a/src/common/abis/__tests__/abi.repository.unit.test.ts b/src/common/abis/__tests__/abi.repository.unit.test.ts index 4a75c9b..07cf619 100644 --- a/src/common/abis/__tests__/abi.repository.unit.test.ts +++ b/src/common/abis/__tests__/abi.repository.unit.test.ts @@ -2,18 +2,17 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Long } from 'mongodb'; -import { Abi } from '../abi'; +import { ContractEncodedAbi } from '../contract-encoded-abi'; const document = { block_number: Long.fromBigInt(100n), contract: 'foo', - hex: 'foo_hex' + hex: 'foo_hex', }; describe('Abi Repository Unit tests', () => { - it('"create" should create Abi instance', async () => { - const abi = Abi.create(100, 'foo', 'foo_hex'); - expect(abi).toBeInstanceOf(Abi); + const abi = ContractEncodedAbi.create(100, 'foo', 'foo_hex'); + expect(abi).toBeInstanceOf(ContractEncodedAbi); }); }); diff --git a/src/common/abis/__tests__/abi.unit.test.ts b/src/common/abis/__tests__/abi.unit.test.ts index e8bee7e..20f440e 100644 --- a/src/common/abis/__tests__/abi.unit.test.ts +++ b/src/common/abis/__tests__/abi.unit.test.ts @@ -2,48 +2,47 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Long } from 'mongodb'; -import { Abi } from '../abi'; +import { ContractEncodedAbi } from '../contract-encoded-abi'; const document = { block_number: Long.fromBigInt(100n), contract: 'foo', - hex: 'foo_hex' + hex: 'foo_hex', }; describe('Abi Unit tests', () => { - it('"create" should create Abi instance', async () => { - const abi = Abi.create(100, 'foo', 'foo_hex'); - expect(abi).toBeInstanceOf(Abi); + const abi = ContractEncodedAbi.create(100, 'foo', 'foo_hex'); + expect(abi).toBeInstanceOf(ContractEncodedAbi); }); it('"fromDocument" should create Abi instance based on docuemnt data', async () => { - const abi = Abi.fromDocument({ + const abi = ContractEncodedAbi.fromDocument({ block_number: Long.fromBigInt(100n), contract: 'foo', - hex: 'foo_hex' + hex: 'foo_hex', }); - expect(abi).toBeInstanceOf(Abi); + expect(abi).toBeInstanceOf(ContractEncodedAbi); expect(abi.blockNumber).toEqual(100n); expect(abi.contract).toEqual('foo'); expect(abi.hex).toEqual('foo_hex'); }); it('"toJson" should return Abi JSON object', async () => { - const abi = Abi.create(100, 'foo', 'foo_hex'); + const abi = ContractEncodedAbi.create(100, 'foo', 'foo_hex'); expect(abi.toJson()).toEqual({ blockNumber: 100n, contract: 'foo', - hex: 'foo_hex' + hex: 'foo_hex', }); }); it('"toDocument" should return mongo document based on Abi data', async () => { - const abi = Abi.create(100, 'foo', 'foo_hex'); + const abi = ContractEncodedAbi.create(100, 'foo', 'foo_hex'); expect(abi.toDocument()).toEqual({ block_number: Long.fromBigInt(100n), contract: 'foo', - hex: 'foo_hex' + hex: 'foo_hex', }); }); }); diff --git a/src/common/abis/abi.ts b/src/common/abis/abi.ts deleted file mode 100644 index a4f62f1..0000000 --- a/src/common/abis/abi.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { MongoDB, parseToBigInt } from '@alien-worlds/api-core'; -import { AbiDocument, AbiJson } from './abis.types'; - -export class Abi { - public static fromDocument(document: AbiDocument): Abi { - const { block_number, contract, hex } = document; - return new Abi(parseToBigInt(block_number), contract, hex); - } - - public static create(blockNumber: unknown, contract: string, hex: string): Abi { - return new Abi(parseToBigInt(blockNumber), contract, hex); - } - - private constructor( - public readonly blockNumber: bigint, - public readonly contract: string, - public readonly hex: string - ) {} - - public toDocument(): AbiDocument { - const { blockNumber, hex, contract } = this; - - return { - block_number: MongoDB.Long.fromBigInt(blockNumber), - hex, - contract, - }; - } - - public toJson(): AbiJson { - const { blockNumber, hex, contract } = this; - - return { - blockNumber, - hex, - contract, - }; - } -} diff --git a/src/common/abis/abis.cache.ts b/src/common/abis/abis.cache.ts index 4962e41..d31bdb8 100644 --- a/src/common/abis/abis.cache.ts +++ b/src/common/abis/abis.cache.ts @@ -1,23 +1,26 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Abi } from './abi'; +import { ContractEncodedAbi } from './contract-encoded-abi'; -const filterFromStartBlock = (startBlock: bigint, endBlock: bigint) => (abi: Abi) => - abi.blockNumber >= startBlock; +const filterFromStartBlock = + (startBlock: bigint, endBlock: bigint) => (abi: ContractEncodedAbi) => + abi.blockNumber >= startBlock; -const filterTillEndBlock = (startBlock: bigint, endBlock: bigint) => (abi: Abi) => - abi.blockNumber <= endBlock; +const filterTillEndBlock = + (startBlock: bigint, endBlock: bigint) => (abi: ContractEncodedAbi) => + abi.blockNumber <= endBlock; -const filterInRange = (startBlock: bigint, endBlock: bigint) => (abi: Abi) => - abi.blockNumber >= startBlock && abi.blockNumber <= endBlock; +const filterInRange = + (startBlock: bigint, endBlock: bigint) => (abi: ContractEncodedAbi) => + abi.blockNumber >= startBlock && abi.blockNumber <= endBlock; export class AbisCache { - private cache: Map> = new Map(); + private cache: Map> = new Map(); public getAbis(options: { startBlock?: bigint; endBlock?: bigint; contracts?: string[]; - }): Abi[] { + }): ContractEncodedAbi[] { const { startBlock, endBlock, contracts } = options; const filter = @@ -60,7 +63,7 @@ export class AbisCache { return abis; } - public getAbi(blockNumber: bigint, contract: string): Abi { + public getAbi(blockNumber: bigint, contract: string): ContractEncodedAbi { if (this.cache.has(contract)) { const abis = this.cache.get(contract); const sorted = Array.from(abis.values()).sort((a, b) => @@ -77,7 +80,7 @@ export class AbisCache { return null; } - public insertAbis(abis: Abi[]): void { + public insertAbis(abis: ContractEncodedAbi[]): void { abis.forEach(abi => { let set = this.cache.get(abi.contract); if (!set) { diff --git a/src/common/abis/abis.repository.ts b/src/common/abis/abis.repository.ts index 0007aea..e4f4314 100644 --- a/src/common/abis/abis.repository.ts +++ b/src/common/abis/abis.repository.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/unbound-method */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { AbiDocument } from './abis.types'; -import { Abi } from './abi'; +import { ContractEncodedAbiDocument } from './abis.types'; +import { ContractEncodedAbi } from './contract-encoded-abi'; import { CollectionMongoSource, DataSourceBulkWriteError, @@ -14,7 +14,7 @@ import { } from '@alien-worlds/api-core'; import { AbisCache } from './abis.cache'; -export class AbisCollection extends CollectionMongoSource { +export class AbisCollection extends CollectionMongoSource { constructor(source: MongoSource) { super(source, 'history_tools.abis', { indexes: [ @@ -39,7 +39,7 @@ export class AbisRepository { startBlock?: bigint; endBlock?: bigint; contracts?: string[]; - }): Promise { + }): Promise { try { const { startBlock, endBlock, contracts } = options || {}; @@ -63,7 +63,7 @@ export class AbisRepository { } const documents = await this.collection.find({ filter }); - const entities = documents.map(Abi.fromDocument); + const entities = documents.map(ContractEncodedAbi.fromDocument); return entities; } catch (error) { @@ -72,7 +72,10 @@ export class AbisRepository { } } - public async getAbi(blockNumber: bigint, contract: string): Promise { + public async getAbi( + blockNumber: bigint, + contract: string + ): Promise { try { const cachedAbi = this.cache.getAbi(blockNumber, contract); @@ -92,14 +95,14 @@ export class AbisRepository { options: { sort: { block_number: -1 }, limit: 1 }, }); - return document ? Abi.fromDocument(document) : null; + return document ? ContractEncodedAbi.fromDocument(document) : null; } catch (error) { log(error); return null; } } - public async insertAbi(abi: Abi): Promise { + public async insertAbi(abi: ContractEncodedAbi): Promise { try { this.cache.insertAbis([abi]); const result = await this.collection.insert(abi.toDocument()); @@ -113,7 +116,7 @@ export class AbisRepository { } } - public async insertAbis(abis: Abi[]): Promise { + public async insertAbis(abis: ContractEncodedAbi[]): Promise { try { this.cache.insertAbis(abis); const documents = abis.map(abi => abi.toDocument()); @@ -136,7 +139,7 @@ export class AbisRepository { public async countAbis(startBlock?: bigint, endBlock?: bigint): Promise { try { - const filter: MongoDB.Filter = {}; + const filter: MongoDB.Filter = {}; if (typeof startBlock === 'bigint') { filter['block_number'] = { $gte: MongoDB.Long.fromBigInt(startBlock) }; } diff --git a/src/common/abis/abis.serialize.ts b/src/common/abis/abis.serialize.ts index 8b5018a..8b89835 100644 --- a/src/common/abis/abis.serialize.ts +++ b/src/common/abis/abis.serialize.ts @@ -1,11 +1,10 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { Serialize } from 'eosjs'; -import abieos from '@eosrio/node-abieos'; import { Authorization, hexToUint8Array } from 'eosjs/dist/eosjs-serialize'; import { Abi } from 'eosjs/dist/eosjs-rpc-interfaces'; -import { AbiTable } from './abis.types'; import { log } from '@alien-worlds/api-core'; +import { AbiTableJson } from '../blockchain/abi'; export type SerializeUtil = { deserializeAction: ( @@ -31,47 +30,42 @@ export class AbisSerialize { hex: string ): T => { try { - if (process.platform === 'linux') { - abieos.load_abi_hex(account, hex); - const type = abieos.get_type_for_action(account, action); - const json = abieos.bin_to_json(account, type, Buffer.from(data)); - return json as T; - } else { - const authorization: Authorization[] = []; - const textEncoder = new TextEncoder(); - const textDecoder = new TextDecoder(); - const bytes = hexToUint8Array(hex); - const abiTypes = Serialize.getTypesFromAbi(Serialize.createAbiTypes()); - const buffer = new Serialize.SerialBuffer({ - textEncoder, - textDecoder, - array: bytes, - }); - buffer.restartRead(); - const abi: Abi = abiTypes.get('abi_def').deserialize(buffer); - const types = Serialize.getTypesFromAbi(Serialize.createInitialTypes(), abi); - const actions = new Map(); - for (const { name, type } of abi.actions) { - actions.set(name, Serialize.getType(types, type)); - } - const contract = { types, actions }; - const deserializedAction = Serialize.deserializeAction( - contract, - account, - action, - authorization, - data, - new TextEncoder(), - new TextDecoder() - ); - - if(!deserializedAction.data) { - log(`Serialized object is empty check the result of "Serialize.deserializeAction"`); - log(deserializedAction); - } + const authorization: Authorization[] = []; + const textEncoder = new TextEncoder(); + const textDecoder = new TextDecoder(); + const bytes = hexToUint8Array(hex); + const abiTypes = Serialize.getTypesFromAbi(Serialize.createAbiTypes()); + const buffer = new Serialize.SerialBuffer({ + textEncoder, + textDecoder, + array: bytes, + }); + buffer.restartRead(); + const abi: Abi = abiTypes.get('abi_def').deserialize(buffer); + const types = Serialize.getTypesFromAbi(Serialize.createInitialTypes(), abi); + const actions = new Map(); + for (const { name, type } of abi.actions) { + actions.set(name, Serialize.getType(types, type)); + } + const contract = { types, actions }; + const deserializedAction = Serialize.deserializeAction( + contract, + account, + action, + authorization, + data, + new TextEncoder(), + new TextDecoder() + ); - return deserializedAction.data as T; + if (!deserializedAction.data) { + log( + `Serialized object is empty check the result of "Serialize.deserializeAction"` + ); + log(deserializedAction); } + + return deserializedAction.data as T; } catch (error) { log(error); return null; @@ -85,48 +79,41 @@ export class AbisSerialize { hex: string ): T => { try { - if (process.platform === 'linux') { - abieos.load_abi_hex(account, hex); - const type = abieos.get_type_for_table(account, table); - const json = abieos.bin_to_json(account, type, Buffer.from(data)); - return json as T; - } else { - const textEncoder = new TextEncoder(); - const textDecoder = new TextDecoder(); - const bytes = hexToUint8Array(hex); - const abiTypes = Serialize.getTypesFromAbi(Serialize.createAbiTypes()); - const buffer = new Serialize.SerialBuffer({ - textEncoder, - textDecoder, - array: bytes, - }); - buffer.restartRead(); - const abi: Abi = abiTypes.get('abi_def').deserialize(buffer); - const types = Serialize.getTypesFromAbi(Serialize.createInitialTypes(), abi); - const actions = new Map(); - for (const { name, type } of abi.actions) { - actions.set(name, Serialize.getType(types, type)); - } - const contract = { types, actions }; + const textEncoder = new TextEncoder(); + const textDecoder = new TextDecoder(); + const bytes = hexToUint8Array(hex); + const abiTypes = Serialize.getTypesFromAbi(Serialize.createAbiTypes()); + const buffer = new Serialize.SerialBuffer({ + textEncoder, + textDecoder, + array: bytes, + }); + buffer.restartRead(); + const abi: Abi = abiTypes.get('abi_def').deserialize(buffer); + const types = Serialize.getTypesFromAbi(Serialize.createInitialTypes(), abi); + const actions = new Map(); + for (const { name, type } of abi.actions) { + actions.set(name, Serialize.getType(types, type)); + } + const contract = { types, actions }; - let this_table: AbiTable, type: string; - for (const t of abi.tables) { - if (t.name === table) { - this_table = t; - break; - } + let this_table: AbiTableJson, type: string; + for (const t of abi.tables) { + if (t.name === table) { + this_table = t; + break; } + } - if (this_table) { - type = this_table.type; - } else { - return null; - } + if (this_table) { + type = this_table.type; + } else { + return null; + } - const sb = new Serialize.SerialBuffer({ textEncoder, textDecoder, array: data }); + const sb = new Serialize.SerialBuffer({ textEncoder, textDecoder, array: data }); - return contract.types.get(type).deserialize(sb) as T; - } + return contract.types.get(type).deserialize(sb) as T; } catch (e) { return null; } diff --git a/src/common/abis/abis.service.ts b/src/common/abis/abis.service.ts index f77c29a..0d5f848 100644 --- a/src/common/abis/abis.service.ts +++ b/src/common/abis/abis.service.ts @@ -2,25 +2,27 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { AbisServiceConfig } from './abis.types'; import fetch from 'node-fetch'; -import { Abi } from './abi'; +import { ContractEncodedAbi } from './contract-encoded-abi'; export class AbisService { constructor(private config: AbisServiceConfig) {} - public async fetchAbis(contract: string): Promise { + public async fetchAbis(contract: string): Promise { try { - const list: Abi[] = []; + const list: ContractEncodedAbi[] = []; const { url, limit, filter } = this.config; const res = await fetch( - `${url}/v2/history/get_actions?account=${contract}&filter=${filter || 'eosio:setabi'}&limit=${ - limit || 100 - }&sort=-1` + `${url}/v2/history/get_actions?account=${contract}&filter=${ + filter || 'eosio:setabi' + }&limit=${limit || 100}&sort=-1` ); const json = await res.json(); for (let i = 0; i < json.actions.length; i++) { const act = json.actions[i]; - list.push(Abi.create(act.block_num, contract, String(act.act.data.abi))); + list.push( + ContractEncodedAbi.create(act.block_num, contract, String(act.act.data.abi)) + ); } return list; } catch (error) { diff --git a/src/common/abis/abis.ts b/src/common/abis/abis.ts index 27c5f7a..8f8c520 100644 --- a/src/common/abis/abis.ts +++ b/src/common/abis/abis.ts @@ -1,13 +1,45 @@ -import { log } from '@alien-worlds/api-core'; +import { MongoConfig, MongoSource, log } from '@alien-worlds/api-core'; import { FeaturedConfig } from '../featured'; -import { Abi } from './abi'; +import { ContractEncodedAbi } from './contract-encoded-abi'; import { AbisServiceNotSetError } from './abis.errors'; -import { AbisRepository } from './abis.repository'; +import { AbisCollection, AbisRepository } from './abis.repository'; import { AbisService } from './abis.service'; +import { AbisServiceConfig } from './abis.types'; export class Abis { + public static async create( + mongo: MongoSource | MongoConfig, + abisConfig?: AbisServiceConfig, + featured?: FeaturedConfig, + setCache?: boolean + ): Promise { + let mongoSource: MongoSource; + + log(` * Abis ... [starting]`); + + if (mongo instanceof MongoSource) { + mongoSource = mongo; + } else { + mongoSource = await MongoSource.create(mongo); + } + const collection = new AbisCollection(mongoSource); + const repository = new AbisRepository(collection); + const service = abisConfig ? new AbisService(abisConfig) : null; + const abis = new Abis(repository, service, featured); + + if (setCache) { + await abis.cacheAbis(); + log(` * Abis cache restored`); + } + + log(` * Abis ... [ready]`); + + return abis; + } + private contracts: Set = new Set(); - constructor( + + private constructor( private repository: AbisRepository, private service?: AbisService, featuredConfig?: FeaturedConfig @@ -39,7 +71,7 @@ export class Abis { endBlock?: bigint; contracts?: string[]; fetch?: boolean; - }): Promise { + }): Promise { const { startBlock, endBlock, contracts, fetch } = options || {}; let abis = await this.repository.getAbis(options); @@ -58,7 +90,7 @@ export class Abis { blockNumber: bigint, contract: string, fetch = false - ): Promise { + ): Promise { let abi = await this.repository.getAbi(blockNumber, contract); if (fetch && !abi) { @@ -81,15 +113,17 @@ export class Abis { contract: string, hex: string ): Promise { - return this.repository.insertAbi(Abi.create(blockNumber, contract, hex)); + return this.repository.insertAbi( + ContractEncodedAbi.create(blockNumber, contract, hex) + ); } - public async fetchAbis(contracts?: string[]): Promise { + public async fetchAbis(contracts?: string[]): Promise { if (!this.service) { throw new AbisServiceNotSetError(); } - const abis: Abi[] = []; + const abis: ContractEncodedAbi[] = []; try { const contractsToFetch = contracts || this.contracts; for (const contract of contractsToFetch) { diff --git a/src/common/abis/abis.types.ts b/src/common/abis/abis.types.ts index 8ce3f66..f1bf80a 100644 --- a/src/common/abis/abis.types.ts +++ b/src/common/abis/abis.types.ts @@ -1,13 +1,13 @@ import { MongoDB, MongoConfig } from '@alien-worlds/api-core'; import { FeaturedConfig } from '../featured'; -export type AbiJson = { +export type ContractEncodedAbiJson = { blockNumber: bigint; contract: string; hex: string; }; -export type AbiDocument = { +export type ContractEncodedAbiDocument = { block_number: MongoDB.Long; contract: string; hex: string; @@ -24,11 +24,3 @@ export type AbisConfig = { mongo: MongoConfig; featured: FeaturedConfig; }; - -export type AbiTable = { - name: string; - type: string; - index_type: string; - key_names: string[]; - key_types: string[]; -}; diff --git a/src/common/abis/abis.utils.ts b/src/common/abis/abis.utils.ts deleted file mode 100644 index 53ba1f2..0000000 --- a/src/common/abis/abis.utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { log, MongoConfig, MongoSource } from '@alien-worlds/api-core'; -import { FeaturedConfig } from '../featured'; -import { Abis } from './abis'; -import { AbisCollection, AbisRepository } from './abis.repository'; -import { AbisService } from './abis.service'; -import { AbisServiceConfig } from './abis.types'; - -export const setupAbis = async ( - mongo: MongoSource | MongoConfig, - abisConfig?: AbisServiceConfig, - featured?: FeaturedConfig, - setCache?: boolean -): Promise => { - let mongoSource: MongoSource; - - log(` * Abis ... [starting]`); - - if (mongo instanceof MongoSource) { - mongoSource = mongo; - } else { - mongoSource = await MongoSource.create(mongo); - } - const collection = new AbisCollection(mongoSource); - const repository = new AbisRepository(collection); - const service = abisConfig ? new AbisService(abisConfig) : null; - const abis = new Abis(repository, service, featured); - - if (setCache) { - await abis.cacheAbis(); - log(` * Abis cache restored`); - } - - log(` * Abis ... [ready]`); - - return abis; -}; diff --git a/src/common/abis/contract-encoded-abi.ts b/src/common/abis/contract-encoded-abi.ts new file mode 100644 index 0000000..c6f1d7e --- /dev/null +++ b/src/common/abis/contract-encoded-abi.ts @@ -0,0 +1,43 @@ +import { MongoDB, parseToBigInt } from '@alien-worlds/api-core'; +import { ContractEncodedAbiDocument, ContractEncodedAbiJson } from './abis.types'; + +export class ContractEncodedAbi { + public static fromDocument(document: ContractEncodedAbiDocument): ContractEncodedAbi { + const { block_number, contract, hex } = document; + return new ContractEncodedAbi(parseToBigInt(block_number), contract, hex); + } + + public static create( + blockNumber: unknown, + contract: string, + hex: string + ): ContractEncodedAbi { + return new ContractEncodedAbi(parseToBigInt(blockNumber), contract, hex); + } + + private constructor( + public readonly blockNumber: bigint, + public readonly contract: string, + public readonly hex: string + ) {} + + public toDocument(): ContractEncodedAbiDocument { + const { blockNumber, hex, contract } = this; + + return { + block_number: MongoDB.Long.fromBigInt(blockNumber), + hex, + contract, + }; + } + + public toJson(): ContractEncodedAbiJson { + const { blockNumber, hex, contract } = this; + + return { + blockNumber, + hex, + contract, + }; + } +} diff --git a/src/common/abis/index.ts b/src/common/abis/index.ts index 127b622..a4c8f59 100644 --- a/src/common/abis/index.ts +++ b/src/common/abis/index.ts @@ -1,9 +1,8 @@ -export * from './abi'; +export * from './contract-encoded-abi'; export * from './abis'; export * from './abis.cache'; export * from './abis.repository'; export * from './abis.service'; export * from './abis.types'; -export * from './abis.utils'; export * from './abis.errors'; export * from './abis.serialize'; diff --git a/src/common/block-range-scanner/__tests__/block-range-scan.mongo.source.unit.test.ts b/src/common/block-range-scanner/__tests__/block-range-scan.mongo.source.unit.test.ts deleted file mode 100644 index 2f70e76..0000000 --- a/src/common/block-range-scanner/__tests__/block-range-scan.mongo.source.unit.test.ts +++ /dev/null @@ -1,279 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { MongoSource } from '@alien-worlds/api-core'; -import { Long } from 'mongodb'; -import { BlockRangeScanMongoSource } from '../block-range-scan.mongo.source'; -import { BlockNumberOutOfRangeError } from '../block-range-scanner.errors'; - -const db = { - databaseName: 'TestDB', - collection: jest.fn(() => ({ - find: jest.fn(), - findOne: jest.fn(), - updateOne: jest.fn(), - insertOne: jest.fn(), - insertMany: jest.fn(), - deleteOne: jest.fn(), - deleteMany: jest.fn(), - countDocuments: jest.fn(), - findOneAndUpdate: jest.fn(), - })) as any, -}; - -const dto = { - _id: { start: 0n, end: 10n, scan_key: 'test', tree_depth: 0, }, - processed_block: 0n, - timestamp: new Date('2022-07-01T09:59:29.035Z'), - is_leaf_node: true, - parent_id: { start: 0n, end: 1n, scan_key: 'test' }, -}; - -const mongoSource = new MongoSource(db as any); - -describe('Block Range scan mongo source Unit tests', () => { - beforeAll(() => { - jest.useFakeTimers(); - jest.setSystemTime(new Date('2022-06-24T19:01:30.911Z')); - }); - - afterAll(() => { - jest.useRealTimers(); - }); - - it('"setCurrentBlockProgress" should throw "scanning already completed" error if dto doesn\'t have is_leaf_node prop', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - - dto.is_leaf_node = undefined; - - await (source as any).setCurrentBlockProgress(dto, 2n).catch(error => { - expect(error.message).toEqual( - `(0-10) range has already completed scanning the blockchain.` - ); - }); - - dto.is_leaf_node = true; - }); - - it('"setCurrentBlockProgress" should find completed parent node when processed block number is penultimate in the range', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - - const findCompletedParentNodeMock = jest - .spyOn(source, 'findCompletedParentNode') - .mockImplementation(); - - await (source as any).setCurrentBlockProgress(dto, 9n); - expect(findCompletedParentNodeMock).toBeCalledWith(dto); - }); - - it('"setCurrentBlockProgress" should set processed_block and timestamp in the range node', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - - await (source as any).setCurrentBlockProgress(dto, 2n); - - const { _id } = dto; - expect((source as any).collection.updateOne).toBeCalledWith( - { _id }, - { - $set: { - processed_block: Long.fromBigInt(2n), - timestamp: new Date(), - }, - } - ); - }); - - it('"startNextScan" should find unscanned or unfinished leaf node, update its timestamp and return that document', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.findOneAndUpdate.mockImplementation(() => ({ - value: dto, - })); - await (source as any).startNextScan('test'); - - expect((source as any).collection.findOneAndUpdate).toBeCalledWith( - { - $and: [ - { is_leaf_node: true }, - { - $or: [ - { timestamp: { $exists: false } }, - { timestamp: { $lt: new Date(Date.now() - 1000) } }, - ], - }, - { '_id.scan_key': 'test' }, - ], - }, - { $set: { timestamp: new Date() } }, - { - sort: { timestamp: 1 }, - returnDocument: 'after', - } - ); - }); - - it('"removeAll" should remove all nodes with the provided scan_key', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - await (source as any).removeAll('test'); - - expect((source as any).collection.deleteMany).toBeCalledWith({ - '_id.scan_key': 'test', - }); - }); - - it('"countScanNodes" should count all nodes with the provided scan_key', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - await (source as any).countScanNodes('test'); - - expect((source as any).collection.countDocuments).toBeCalledWith({ - $and: [{ '_id.scan_key': 'test' }], - }); - }); - - it('"countScanNodes" should count all nodes with the provided scan_key within range', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - await (source as any).countScanNodes('test', 1n, 1n); - const options = [ - { '_id.scan_key': 'test' }, - { '_id.start': { $gte: Long.fromBigInt(1n) } }, - { '_id.end': { $lte: Long.fromBigInt(1n) } }, - ]; - expect((source as any).collection.countDocuments).toBeCalledWith({ - $and: options, - }); - }); - - it('"hasScanKey" should return true when a matching document is found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.findOne.mockImplementation(() => dto); - - await (source as any).hasScanKey('test'); - - expect((source as any).collection.findOne).toBeCalledWith({ - $and: [{ '_id.scan_key': 'test' }], - }); - }); - - it('"hasScanKey" should return false when no matching document was found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.findOne.mockImplementation(() => null); - const options = [ - { '_id.scan_key': 'test' }, - { '_id.start': Long.fromBigInt(1n) }, - { '_id.end': Long.fromBigInt(1n) }, - ]; - await (source as any).hasScanKey('test', 1n, 1n); - - expect((source as any).collection.findOne).toBeCalledWith({ - $and: options, - }); - }); - - it('"hasUnscannedNodes" should return true when a matching document is found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.findOne.mockImplementation(() => dto); - - await (source as any).hasUnscannedNodes('test'); - - expect((source as any).collection.findOne).toBeCalledWith({ - $and: [ - { '_id.scan_key': 'test' }, - { '_id.tree_depth': { $gt: 0 } }, - { is_leaf_node: true }, - ], - }); - }); - - it('"hasUnscannedNodes" should return false when no matching document was found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.findOne.mockImplementation(() => null); - const options = [ - { '_id.scan_key': 'test' }, - { '_id.tree_depth': { $gt: 0 } }, - { is_leaf_node: true }, - { 'parent_id.start': Long.fromBigInt(1n) }, - { 'parent_id.end': Long.fromBigInt(1n) }, - ]; - await (source as any).hasUnscannedNodes('test', 1n, 1n); - - expect((source as any).collection.findOne).toBeCalledWith({ - $and: options, - }); - }); - - it('"findRangeForBlockNumber" should return a range node that matches the key and contains the given block number in the range', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - (source as any).collection.find.mockImplementation(() => ({ - next: () => dto, - })); - - await (source as any).findRangeForBlockNumber(0n, 'test'); - - expect((source as any).collection.find).toBeCalledWith( - { - '_id.start': { $lte: Long.fromBigInt(0n) }, - '_id.end': { $gt: Long.fromBigInt(0n) }, - '_id.tree_depth': { $gt: 0 }, - '_id.scan_key': 'test', - }, - { sort: { '_id.tree_depth': -1 } } - ); - }); - - it('"findRangeForBlockNumber" should not do anything when given document has no parent_id', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - - (source as any).collection.find.mockImplementation(() => ({ - next: () => dto, - })); - - await (source as any).findCompletedParentNode({_id: { tree_depth: 0 }}); - - expect((source as any).collection.deleteOne).not.toBeCalled(); - expect((source as any).collection.find).not.toBeCalled(); - }); - - it('"findRangeForBlockNumber" should remove given document when it contains parent_id and fetch its child nodes', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - - (source as any).collection.find.mockImplementation(async () => ({ - count: () => 1, - })); - - await (source as any).findCompletedParentNode(dto); - - expect((source as any).collection.deleteOne).toBeCalledWith({ - _id: dto._id, - }); - expect((source as any).collection.countDocuments).toBeCalledWith({ - parent_id: dto.parent_id, - }); - }); - - it('"updateProcessedBlockNumber" should call findCompletedParentNode on parent node if no child nodes were found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - const findRangeForBlockNumberMock = jest - .spyOn(source as any, 'findRangeForBlockNumber') - .mockImplementation(() => ({})); - const setCurrentBlockProgressMock = jest - .spyOn(source as any, 'setCurrentBlockProgress') - .mockImplementation(); - - await source.updateProcessedBlockNumber('test', 0n); - - expect(findRangeForBlockNumberMock).toBeCalled(); - expect(setCurrentBlockProgressMock).toBeCalled(); - }); - - it('"updateProcessedBlockNumber" should throw an error when no block range was found', async () => { - const source = new BlockRangeScanMongoSource(mongoSource); - const findRangeForBlockNumberMock = jest - .spyOn(source as any, 'findRangeForBlockNumber') - .mockImplementation(() => null); - - await source.updateProcessedBlockNumber('test', 0n).catch(error => { - expect(error).toBeInstanceOf(BlockNumberOutOfRangeError); - }); - - findRangeForBlockNumberMock.mockClear(); - }); -}); diff --git a/src/common/block-range-scanner/__tests__/block-range-scan.repository.unit.test.ts b/src/common/block-range-scanner/__tests__/block-range-scan.repository.unit.test.ts deleted file mode 100644 index b56e0e3..0000000 --- a/src/common/block-range-scanner/__tests__/block-range-scan.repository.unit.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { Failure, MongoSource } from '@alien-worlds/api-core'; -import { BlockRangeScan } from '../block-range-scan'; -import { BlockRangeScanMongoSource } from '../block-range-scan.mongo.source'; -import { BlockRangeScanRepository } from '../block-range-scan.repository'; - -const blockRangeScanConfig = { - maxChunkSize: 0, - scanKey: 'test', -}; - -const db = { - databaseName: 'TestDB', - collection: jest.fn(() => ({ - find: jest.fn(), - findOne: jest.fn(), - updateOne: jest.fn(), - insertOne: jest.fn(), - insertMany: jest.fn(), - deleteOne: jest.fn(), - deleteMany: jest.fn(), - countDocuments: jest.fn(), - findOneAndUpdate: jest.fn(), - })) as any, -}; - -const dto = { - _id: { start: 0n, end: 10n, scan_key: 'test' }, - tree_depth: 0, - processed_block: 0n, - time_stamp: new Date('2022-07-01T09:59:29.035Z'), - is_leaf_node: true, - parent_id: { start: 0n, end: 1n, scan_key: 'test' }, -}; - -const mongoSource = new MongoSource(db as any); -const blockRangeScanMongoSource = new BlockRangeScanMongoSource(mongoSource); - -describe('Block Range scan repository Unit tests', () => { - beforeAll(() => { - jest.useFakeTimers(); - jest.setSystemTime(new Date('2022-06-24T19:01:30.911Z')); - }); - - afterAll(() => { - jest.useRealTimers(); - }); - - it('"startNextScan" should return a result with BlockRangeScan object', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const startNextScanMock = jest - .spyOn(blockRangeScanMongoSource, 'startNextScan') - .mockImplementation(() => dto as any); - - const result = await repo.startNextScan('test'); - - expect(result).toBeInstanceOf(BlockRangeScan); - - startNextScanMock.mockClear(); - }); - - it('"startNextScan" should return null when no block range node was found for the given key', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const startNextScanMock = jest - .spyOn(blockRangeScanMongoSource, 'startNextScan') - .mockImplementation(() => { - throw new Error(); - }); - const result = await repo.startNextScan('test'); - - expect(result).toBeNull(); - - startNextScanMock.mockClear(); - }); - - it('"createScanNodes" should insert multiple scan nodes to the source', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const createChildRangesMock = jest.fn().mockImplementation(() => []); - - BlockRangeScan.createChildRanges = createChildRangesMock; - const insertManyMock = jest - .spyOn(blockRangeScanMongoSource, 'insertMany') - .mockImplementation(async () => []); - - const result = await repo.createScanNodes('test', 0n, 1n); - - expect(createChildRangesMock).toBeCalled(); - expect(insertManyMock).toBeCalled(); - expect(result).toBeTruthy(); - - insertManyMock.mockClear(); - createChildRangesMock.mockClear(); - }); - - it('"createScanNodes" should return false on any error', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const createMock = jest.fn().mockImplementation(() => { - throw new Error(); - }); - BlockRangeScan.create = createMock; - - const result = await repo.createScanNodes('test', 0n, 1n); - - expect(createMock).toBeCalled(); - expect(result.error).toBeInstanceOf(Error); - - createMock.mockClear(); - }); - - it('"countScanNodes" should result with number of nodes', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const countScanNodesMock = jest - .spyOn(blockRangeScanMongoSource, 'countScanNodes') - .mockImplementation(async () => 6); - - const result = await repo.countScanNodes('test', 0n, 1n); - - expect(countScanNodesMock).toBeCalled(); - expect(result).toEqual(6); - - countScanNodesMock.mockClear(); - }); - - it('"removeAll" should result with number of nodes', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const removeAllMock = jest - .spyOn(blockRangeScanMongoSource, 'removeAll') - .mockImplementation(); - - const result = await repo.removeAll('test'); - - expect(removeAllMock).toBeCalled(); - - removeAllMock.mockClear(); - }); - - it('"hasScanKey" should result with boolean value', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const hasScanKeyMock = jest - .spyOn(blockRangeScanMongoSource, 'hasScanKey') - .mockImplementation(async () => true); - - const result = await repo.hasScanKey('test'); - - expect(hasScanKeyMock).toBeCalled(); - expect(result).toEqual(true); - - hasScanKeyMock.mockClear(); - }); - - it('"hasUnscannedNodes" should result with boolean value', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const hasUnscannedNodesMock = jest - .spyOn(blockRangeScanMongoSource, 'hasUnscannedNodes') - .mockImplementation(async () => true); - - const result = await repo.hasUnscannedNodes('test'); - - expect(hasUnscannedNodesMock).toBeCalled(); - expect(result).toEqual(true); - - hasUnscannedNodesMock.mockClear(); - }); - - it('"updateScannedBlockNumber" should call source.updateProcessedBlockNumber and result with no content', async () => { - const repo = new BlockRangeScanRepository( - blockRangeScanMongoSource, - blockRangeScanConfig - ); - const updateScannedBlockNumberMock = jest - .spyOn(blockRangeScanMongoSource, 'updateProcessedBlockNumber') - .mockImplementation(); - - const result = await repo.updateScannedBlockNumber('test', 0n); - - expect(updateScannedBlockNumberMock).toBeCalled(); - - updateScannedBlockNumberMock.mockClear(); - }); -}); diff --git a/src/common/block-range-scanner/__tests__/block-range-scan.unit.test.ts b/src/common/block-range-scanner/__tests__/block-range-scan.unit.test.ts deleted file mode 100644 index 3afb9da..0000000 --- a/src/common/block-range-scanner/__tests__/block-range-scan.unit.test.ts +++ /dev/null @@ -1,156 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { Long } from 'mongodb'; -import { BlockRangeScan, BlockRangeScanParent } from '../block-range-scan'; - -const document = { - _id: { - start: Long.fromBigInt(1n), - end: Long.fromBigInt(2n), - scan_key: 'test', - tree_depth: 0, - }, - processed_block: Long.fromBigInt(1n), - timestamp: new Date('2022-06-24T19:01:30.911Z'), - is_leaf_node: false, - parent_id: { - start: Long.fromBigInt(0n), - end: Long.fromBigInt(10n), - scan_key: 'test', - tree_depth: 0, - }, -}; - -describe('Block Range scan entity Unit tests', () => { - beforeAll(() => { - jest.useFakeTimers(); - jest.setSystemTime(new Date('2022-06-24T19:01:30.911Z')); - }); - - afterAll(() => { - jest.useRealTimers(); - }); - - it('"create" should create an entity based on data', async () => { - const parent = BlockRangeScanParent.create(0n, 10n, 'test', 0); - const entity = BlockRangeScan.create( - 1n, - 2n, - 'test', - 0, - parent, - false, - 0n, - new Date('2022-06-24T19:01:30.911Z') - ); - - expect(entity.processedBlock).toEqual(0n); - expect(entity.start).toEqual(1n); - expect(entity.end).toEqual(2n); - expect(entity.isLeafNode).toEqual(false); - expect(entity.timestamp.toISOString()).toEqual('2022-06-24T19:01:30.911Z'); - expect(entity.parent.start).toEqual(0n); - expect(entity.parent.end).toEqual(10n); - expect(entity.parent.scanKey).toEqual('test'); - expect(entity.scanKey).toEqual('test'); - expect(entity.treeDepth).toEqual(0); - }); - - it('"fromDocument" should create an entity based on source document', async () => { - const entity = BlockRangeScan.fromDocument(document); - - expect(entity.processedBlock).toEqual(1n); - expect(entity.start).toEqual(1n); - expect(entity.end).toEqual(2n); - expect(entity.isLeafNode).toEqual(false); - expect(entity.timestamp.toISOString()).toEqual('2022-06-24T19:01:30.911Z'); - expect(entity.parent.start).toEqual(0n); - expect(entity.parent.end).toEqual(10n); - expect(entity.parent.scanKey).toEqual('test'); - expect(entity.scanKey).toEqual('test'); - expect(entity.treeDepth).toEqual(0); - }); - - it('"createChildRanges" should create an entity based on source document', async () => { - const ranges = BlockRangeScan.createChildRanges( - BlockRangeScan.create(0n, 10n, 'test', 0), - 4 - ); - const jsons = ranges.map(range => range.toJson()).sort((a, b) => a.start > b.start ? 1 : -1); - - expect(jsons).toEqual([ - { - end: 4n, - isLeafNode: true, - parent: { - end: 10n, - scanKey: "test", - start: 0n, - treeDepth: 0, - }, - scanKey: "test", - start: 0n, - treeDepth: 1, - }, - { - end: 8n, - isLeafNode: true, - parent: { - end: 10n, - scanKey: "test", - start: 0n, - treeDepth: 0, - }, - scanKey: "test", - start: 4n, - treeDepth: 1, - }, - { - end: 10n, - isLeafNode: true, - parent: { - end: 10n, - scanKey: "test", - start: 0n, - treeDepth: 0, - }, - scanKey: "test", - start: 8n, - treeDepth: 1, - }, - ]); - }); - - it('"setAsLeafNode" should set isLeafNode prop to true', async () => { - const entity = BlockRangeScan.fromDocument(document); - - expect(entity.isLeafNode).toEqual(false); - entity.setAsLeafNode(); - expect(entity.isLeafNode).toEqual(true); - }); - - it('"toDocument" should create source document based on entity', async () => { - const entity = BlockRangeScan.fromDocument(document); - expect(entity.toDocument()).toEqual(document); - }); - - it('"toJson" should create json object based on entity', async () => { - const entity = BlockRangeScan.fromDocument(document); - expect(entity.toJson()).toEqual({ - processedBlock: 1n, - end: 2n, - isLeafNode: false, - parent: { - end: 10n, - scanKey: 'test', - start: 0n, - treeDepth: 0, - }, - scanKey: 'test', - start: 1n, - timestamp: new Date('2022-06-24T19:01:30.911Z'), - treeDepth: 0, - }); - }); -}); diff --git a/src/common/block-range-scanner/__tests__/block-range-scanner.unit.test.ts b/src/common/block-range-scanner/__tests__/block-range-scanner.unit.test.ts deleted file mode 100644 index eb4e26d..0000000 --- a/src/common/block-range-scanner/__tests__/block-range-scanner.unit.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { BlockRangeScanRepository } from "../block-range-scan.repository"; -import { BlockRangeScanner } from "../block-range-scanner"; - -jest.mock('../block-range-scan.repository', () => ({ - BlockRangeScanRepository: jest.fn(() => ({ - hasScanKey: jest.fn(), - createScanNodes: jest.fn(), - startNextScan: jest.fn(), - hasUnscannedNodes: jest.fn(), - updateScannedBlockNumber: jest.fn(), - })) -})); - -jest.mock('mongodb'); - -const config = { - maxChunkSize: 10, - scanKey: 'test', -}; - -describe('Block Range Scanner Unit tests', () => { - - it('"createScanNodes" should call hasScanKey and createScanNodes when scan key is available', async () => { - const repo = new BlockRangeScanRepository({} as any, config); - const scanner = new BlockRangeScanner(repo); - await scanner.createScanNodes('test', 0n, 10n) - - expect(repo.hasScanKey).toBeCalled(); - expect(repo.createScanNodes).toBeCalled(); - }); - - it('"createScanNodes" should call only hasScanKey when scan key is not available', async () => { - const repo = new BlockRangeScanRepository({} as any, config); - const scanner = new BlockRangeScanner(repo); - - (repo.hasScanKey as any).mockImplementation(() => true) - - await scanner.createScanNodes('test', 0n, 10n) - - expect(repo.hasScanKey).toBeCalled(); - expect(repo.createScanNodes).not.toBeCalled(); - }); - - it('"getNextScanNode" should call startNextScan and return its value', async () => { - const repo = new BlockRangeScanRepository({} as any, config); - const scanner = new BlockRangeScanner(repo); - - (repo.startNextScan as any).mockImplementation(() => ({ mockedScan: true })) - - const result = await scanner.getNextScanNode(''); - - expect(repo.startNextScan).toBeCalled(); - expect(result).toEqual({ mockedScan: true }); - }); - - it('"hasUnscannedBlocks" should call startNextScan and return its value', async () => { - const repo = new BlockRangeScanRepository({} as any, config); - const scanner = new BlockRangeScanner(repo); - - (repo.hasUnscannedNodes as any).mockImplementation(() => false) - - const result = await scanner.hasUnscannedBlocks(''); - - expect(repo.hasUnscannedNodes).toBeCalled(); - expect(result).toEqual(false); - }); - - it('"updateScanProgress" should call updateScannedBlockNumber', async () => { - const repo = new BlockRangeScanRepository({} as any, config); - const scanner = new BlockRangeScanner(repo); - - await scanner.updateScanProgress('', 1n); - - expect(repo.updateScannedBlockNumber).toBeCalled(); - }); -}); diff --git a/src/common/block-range-scanner/__tests__/block-range-scanner.utils.unit.test.ts b/src/common/block-range-scanner/__tests__/block-range-scanner.utils.unit.test.ts deleted file mode 100644 index 9259ce9..0000000 --- a/src/common/block-range-scanner/__tests__/block-range-scanner.utils.unit.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { MongoSource } from "@alien-worlds/api-core"; -import { BlockRangeScanner } from "../block-range-scanner"; -import { setupBlockRangeScanner } from "../block-range-scanner.utils"; - -jest.mock('@alien-worlds/api-core/build/storage/data/data-sources/mongo.helpers', () => ({ - connectMongo: jest.fn(() => ({ - collection: () => jest.fn() - })), -})); - -jest.mock('mongodb'); - -let findMock; -let countMock; -let deleteOneMock; -let deleteManyMock; -let aggregateMock; -let findOneMock; -let updateOneMock; -let updateManyMock; -let bulkWriteMock; -let insertOneMock; -let insertManyMock; - -const db = { - databaseName: 'TestDB', - collection: jest.fn(() => ({ - find: jest.fn(() => findMock()), - countDocuments: jest.fn(() => countMock()), - aggregate: jest.fn(() => aggregateMock()), - findOne: jest.fn(() => findOneMock()), - bulkWrite: jest.fn(() => bulkWriteMock()), - updateOne: jest.fn(() => updateOneMock()), - updateMany: jest.fn(() => updateManyMock()), - insertOne: jest.fn(() => insertOneMock()), - insertMany: jest.fn(() => insertManyMock()), - deleteOne: jest.fn(() => deleteOneMock()), - deleteMany: jest.fn(() => deleteManyMock()), - })) as any, -}; - -const config = { - maxChunkSize: 10, - scanKey: 'test', -}; - -const mongoConfig = { - hosts: [''], - database: '', -}; - -const mongoSource = new MongoSource(db as any); - -describe('Block Range Scan utils Unit tests', () => { - - it('"setupBlockRangeScanner" should return block range scanner instance', async () => { - let scanner; - scanner = await setupBlockRangeScanner(mongoSource, config); - expect(scanner).toBeInstanceOf(BlockRangeScanner); - - scanner = await setupBlockRangeScanner(mongoConfig, config); - expect(scanner).toBeInstanceOf(BlockRangeScanner); - }); -}); diff --git a/src/common/block-range-scanner/block-range-scanner.utils.ts b/src/common/block-range-scanner/block-range-scanner.utils.ts deleted file mode 100644 index 575d08b..0000000 --- a/src/common/block-range-scanner/block-range-scanner.utils.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { log, MongoConfig, MongoSource } from '@alien-worlds/api-core'; -import { BlockRangeScanMongoSource } from './block-range-scan.mongo.source'; -import { BlockRangeScanRepository } from './block-range-scan.repository'; -import { BlockRangeScanner } from './block-range-scanner'; -import { BlockRangeScanConfig } from './block-range-scanner.config'; - -export const setupBlockRangeScanner = async ( - mongo: MongoSource | MongoConfig, - config: BlockRangeScanConfig -): Promise => { - let mongoSource: MongoSource; - - log(` * Block Range Scanner ... [starting]`); - - if (mongo instanceof MongoSource) { - mongoSource = mongo; - } else { - mongoSource = await MongoSource.create(mongo); - } - const source = new BlockRangeScanMongoSource(mongoSource); - const repository = new BlockRangeScanRepository(source, config); - const scanner: BlockRangeScanner = new BlockRangeScanner(repository); - - log(` * Block Range Scanner ... [ready]`); - return scanner; -}; diff --git a/src/common/block-state/block-state.source.ts b/src/common/block-state/block-state.source.ts index 717c162..e5b66d9 100644 --- a/src/common/block-state/block-state.source.ts +++ b/src/common/block-state/block-state.source.ts @@ -45,17 +45,15 @@ export class BlockStateSource extends CollectionMongoSource * * @param {bigint} value */ - public async updateBlockNumber(value: bigint): Promise { + public async updateBlockNumber(value: bigint): Promise { const result = await this.update( - { $max: { block_number: MongoDB.Long.fromBigInt(value) } }, + { + $max: { block_number: MongoDB.Long.fromBigInt(value) }, + $set: { last_modified_timestamp: new Date() }, + }, { options: { upsert: true } } ); - if (result) { - await this.update( - { last_modified_timestamp: new Date() }, - { options: { upsert: true } } - ); - } + return !!result; } public async removeActions(labels: string[]): Promise { diff --git a/src/common/block-state/block-state.ts b/src/common/block-state/block-state.ts index fd1a2f0..3db814e 100644 --- a/src/common/block-state/block-state.ts +++ b/src/common/block-state/block-state.ts @@ -1,33 +1,61 @@ -import { log, MongoSource, parseToBigInt } from '@alien-worlds/api-core'; +import { + Failure, + log, + MongoConfig, + MongoSource, + parseToBigInt, + Result, +} from '@alien-worlds/api-core'; import { BlockStateSource } from './block-state.source'; import { BlockStateData } from './block-state.types'; export class BlockState { + public static async create(mongo: MongoSource | MongoConfig) { + log(` * Block State ... [starting]`); + + let state: BlockState; + + if (mongo instanceof MongoSource) { + state = new BlockState(mongo); + } else { + const mongoSource = await MongoSource.create(mongo); + state = new BlockState(mongoSource); + } + + log(` * Block State ... [ready]`); + return state; + } + private source: BlockStateSource; - constructor(mongo: MongoSource) { + private constructor(mongo: MongoSource) { this.source = new BlockStateSource(mongo); } - public async getState(): Promise { - const state = await this.source.getState(); + public async getState(): Promise> { + try { + const state = await this.source.getState(); + let data: BlockStateData; + if (state) { + const { last_modified_timestamp, actions, tables, block_number } = state; + data = { + lastModifiedTimestamp: last_modified_timestamp || new Date(), + actions: actions || [], + tables: tables || [], + blockNumber: parseToBigInt(block_number) || 0n, + }; + } - if (state) { - const { last_modified_timestamp, actions, tables, block_number } = state; - return { - lastModifiedTimestamp: last_modified_timestamp || new Date(), - actions: actions || [], - tables: tables || [], - blockNumber: parseToBigInt(block_number) || 0n, + data = { + lastModifiedTimestamp: new Date(), + actions: [], + tables: [], + blockNumber: 0n, }; + return Result.withContent(data); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); } - - return { - lastModifiedTimestamp: new Date(), - actions: [], - tables: [], - blockNumber: 0n, - }; } /** @@ -36,8 +64,13 @@ export class BlockState { * * @param {bigint} value */ - public async newState(block_number: bigint): Promise { - await this.source.updateBlockNumber(block_number); + public async newState(blockNumber: bigint): Promise { + try { + await this.source.updateBlockNumber(blockNumber); + return Result.withoutContent(); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } } /** @@ -46,21 +79,26 @@ export class BlockState { * * @param {bigint} value */ - public async updateBlockNumber(value: bigint): Promise { - return this.source.updateBlockNumber(value); + public async updateBlockNumber(value: bigint): Promise> { + try { + const isUpdated = await this.source.updateBlockNumber(value); + + return Result.withContent(isUpdated); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } } /** * Returns current block number or -1 * @returns */ - public async getBlockNumber(): Promise { - const currentBlockNumber = await this.source.getBlockNumber(); - log( - `Current state block number: ${ - currentBlockNumber ? currentBlockNumber.toString() : currentBlockNumber - }` - ); - return currentBlockNumber; + public async getBlockNumber(): Promise> { + try { + const currentBlockNumber = await this.source.getBlockNumber(); + return Result.withContent(currentBlockNumber); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } } } diff --git a/src/common/block-state/block-state.utils.ts b/src/common/block-state/block-state.utils.ts deleted file mode 100644 index 94cf71f..0000000 --- a/src/common/block-state/block-state.utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { log, MongoConfig, MongoSource } from '@alien-worlds/api-core'; -import { BlockState } from './block-state'; - -export const setupBlockState = async (mongo: MongoSource | MongoConfig) => { - log(` * Block State ... [starting]`); - - let state: BlockState; - - if (mongo instanceof MongoSource) { - state = new BlockState(mongo); - } else { - const mongoSource = await MongoSource.create(mongo); - state = new BlockState(mongoSource); - } - - log(` * Block State ... [ready]`); - return state; -}; diff --git a/src/common/block-state/index.ts b/src/common/block-state/index.ts index 953d660..8bb1413 100644 --- a/src/common/block-state/index.ts +++ b/src/common/block-state/index.ts @@ -1,3 +1,2 @@ export * from './block-state'; export * from './block-state.source'; -export * from './block-state.utils'; diff --git a/src/common/blockchain/block-content/abi/__tests__/abi.unit.test.ts b/src/common/blockchain/abi/__tests__/abi.unit.test.ts similarity index 96% rename from src/common/blockchain/block-content/abi/__tests__/abi.unit.test.ts rename to src/common/blockchain/abi/__tests__/abi.unit.test.ts index 0e6f44c..d92eb00 100644 --- a/src/common/blockchain/block-content/abi/__tests__/abi.unit.test.ts +++ b/src/common/blockchain/abi/__tests__/abi.unit.test.ts @@ -174,12 +174,12 @@ describe('Table Unit tests', () => { describe('Abi Unit tests', () => { it('"fromDto" should create entity', () => { - const entity = Abi.fromDto(abiDto); - expect(entity.toDto()).toEqual(abiDto); + const entity = Abi.fromJson(abiDto); + expect(entity.toJson()).toEqual(abiDto); }); it('"toDto" should create dto from entity', () => { - const entity = Abi.fromDto(abiDto); - expect(entity.toDto()).toEqual(abiDto); + const entity = Abi.fromJson(abiDto); + expect(entity.toJson()).toEqual(abiDto); }); }); diff --git a/src/common/blockchain/block-content/abi/abi-action.ts b/src/common/blockchain/abi/abi-action.ts similarity index 80% rename from src/common/blockchain/block-content/abi/abi-action.ts rename to src/common/blockchain/abi/abi-action.ts index 97d4047..80be518 100644 --- a/src/common/blockchain/block-content/abi/abi-action.ts +++ b/src/common/blockchain/abi/abi-action.ts @@ -1,4 +1,4 @@ -import { AbiActionDto } from './abi.dtos'; +import { AbiActionJson } from './abi.dtos'; /** * @class @@ -17,9 +17,9 @@ export class AbiAction { ) {} /** - * @returns {AbiActionDto} + * @returns {AbiActionJson} */ - public toDto(): AbiActionDto { + public toDto(): AbiActionJson { const { name, type, ricardianContract } = this; return { name, @@ -30,10 +30,10 @@ export class AbiAction { /** * @static - * @param {AbiActionDto} dto + * @param {AbiActionJson} dto * @returns {AbiAction} */ - public static fromDto(dto: AbiActionDto): AbiAction { + public static fromDto(dto: AbiActionJson): AbiAction { const { name, type, ricardian_contract } = dto; return new AbiAction(name, type, ricardian_contract); } diff --git a/src/common/blockchain/block-content/abi/abi-error-message.ts b/src/common/blockchain/abi/abi-error-message.ts similarity index 68% rename from src/common/blockchain/block-content/abi/abi-error-message.ts rename to src/common/blockchain/abi/abi-error-message.ts index f28147a..1408241 100644 --- a/src/common/blockchain/block-content/abi/abi-error-message.ts +++ b/src/common/blockchain/abi/abi-error-message.ts @@ -1,4 +1,4 @@ -import { AbiErrorMessageDto } from './abi.dtos'; +import { AbiErrorMessageJson } from './abi.dtos'; /** * @class @@ -15,19 +15,19 @@ export class AbiErrorMessage { ) {} /** - * @returns {AbiErrorMessageDto} + * @returns {AbiErrorMessageJson} */ - public toDto(): AbiErrorMessageDto { + public toDto(): AbiErrorMessageJson { const { errorCode, message } = this; return { error_code: errorCode, error_msg: message }; } /** * @static - * @param {AbiErrorMessageDto} dto + * @param {AbiErrorMessageJson} dto * @returns {AbiErrorMessage} */ - public static fromDto(dto: AbiErrorMessageDto): AbiErrorMessage { + public static fromDto(dto: AbiErrorMessageJson): AbiErrorMessage { const { error_code, error_msg } = dto; return new AbiErrorMessage(error_code, error_msg); } diff --git a/src/common/blockchain/block-content/abi/abi-extension.ts b/src/common/blockchain/abi/abi-extension.ts similarity index 65% rename from src/common/blockchain/block-content/abi/abi-extension.ts rename to src/common/blockchain/abi/abi-extension.ts index 7b204f0..eccb994 100644 --- a/src/common/blockchain/block-content/abi/abi-extension.ts +++ b/src/common/blockchain/abi/abi-extension.ts @@ -1,4 +1,4 @@ -import { AbiExtensionDto } from './abi.dtos'; +import { AbiExtensionJson } from './abi.dtos'; /** * @class @@ -12,19 +12,19 @@ export class AbiExtension { private constructor(public readonly tag: number, public readonly value: string) {} /** - * @returns {AbiExtensionDto} + * @returns {AbiExtensionJson} */ - public toDto(): AbiExtensionDto { + public toDto(): AbiExtensionJson { const { tag, value } = this; return { tag, value }; } /** * @static - * @param {AbiExtensionDto} dto + * @param {AbiExtensionJson} dto * @returns {AbiExtension} */ - public static fromDto(dto: AbiExtensionDto): AbiExtension { + public static fromDto(dto: AbiExtensionJson): AbiExtension { const { tag, value } = dto; return new AbiExtension(tag, value); } diff --git a/src/common/blockchain/block-content/abi/abi-struct.ts b/src/common/blockchain/abi/abi-struct.ts similarity index 77% rename from src/common/blockchain/block-content/abi/abi-struct.ts rename to src/common/blockchain/abi/abi-struct.ts index 3bbe6db..501b226 100644 --- a/src/common/blockchain/block-content/abi/abi-struct.ts +++ b/src/common/blockchain/abi/abi-struct.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import { AbiStructDto, FieldDto } from './abi.dtos'; +import { AbiStructJson, FieldJson } from './abi.dtos'; /** * @class @@ -13,19 +13,19 @@ export class StructField { private constructor(public readonly name: string, public readonly type: string) {} /** - * @returns {FieldDto} + * @returns {FieldJson} */ - public toDto(): FieldDto { + public toDto(): FieldJson { const { name, type } = this; return { name, type }; } /** * @static - * @param {FieldDto} dto + * @param {FieldJson} dto * @returns {StructField} */ - public static fromDto(dto: FieldDto): StructField { + public static fromDto(dto: FieldJson): StructField { const { name, type } = dto; return new StructField(name, type); } @@ -48,9 +48,9 @@ export class AbiStruct { ) {} /** - * @returns {AbiStructDto} + * @returns {AbiStructJson} */ - public toDto(): AbiStructDto { + public toDto(): AbiStructJson { return { name: this.name, base: this.base, @@ -60,10 +60,10 @@ export class AbiStruct { /** * @static - * @param {AbiStructDto} dto + * @param {AbiStructJson} dto * @returns {AbiStruct} */ - public static fromDto(dto: AbiStructDto): AbiStruct { + public static fromDto(dto: AbiStructJson): AbiStruct { const { name, base, fields } = dto; return new AbiStruct(name, base, fields.map(StructField.fromDto)); } diff --git a/src/common/blockchain/block-content/abi/abi-table.ts b/src/common/blockchain/abi/abi-table.ts similarity index 85% rename from src/common/blockchain/block-content/abi/abi-table.ts rename to src/common/blockchain/abi/abi-table.ts index f952a8f..7392898 100644 --- a/src/common/blockchain/block-content/abi/abi-table.ts +++ b/src/common/blockchain/abi/abi-table.ts @@ -1,4 +1,4 @@ -import { AbiTableDto } from './abi.dtos'; +import { AbiTableJson } from './abi.dtos'; /** * @class @@ -21,9 +21,9 @@ export class AbiTable { ) {} /** - * @returns {AbiTableDto} + * @returns {AbiTableJson} */ - public toDto(): AbiTableDto { + public toDto(): AbiTableJson { const { name, type, indexType, keyNames, keyTypes } = this; return { name, @@ -36,10 +36,10 @@ export class AbiTable { /** * @static - * @param {AbiTableDto} dto + * @param {AbiTableJson} dto * @returns {AbiTable} */ - public static fromDto(dto: AbiTableDto): AbiTable { + public static fromDto(dto: AbiTableJson): AbiTable { const { name, type, index_type, key_names, key_types } = dto; return new AbiTable(name, type, index_type, key_names, key_types); } diff --git a/src/common/blockchain/block-content/abi/abi-type.ts b/src/common/blockchain/abi/abi-type.ts similarity index 75% rename from src/common/blockchain/block-content/abi/abi-type.ts rename to src/common/blockchain/abi/abi-type.ts index 0088a02..70352ed 100644 --- a/src/common/blockchain/block-content/abi/abi-type.ts +++ b/src/common/blockchain/abi/abi-type.ts @@ -1,4 +1,4 @@ -import { AbiTypeDto } from './abi.dtos'; +import { AbiTypeJson } from './abi.dtos'; /** * Type entity @@ -17,9 +17,9 @@ export class AbiType { /** * Parse Type entity to DTO - * @returns {AbiTypeDto} + * @returns {AbiTypeJson} */ - public toDto(): AbiTypeDto { + public toDto(): AbiTypeJson { return { new_type_name: this.newTypeName, type: this.type, @@ -30,10 +30,10 @@ export class AbiType { * Create ABI entity based on provided DTO * * @static - * @param {AbiTypeDto} dto + * @param {AbiTypeJson} dto * @returns {AbiType} */ - public static fromDto(dto: AbiTypeDto): AbiType { + public static fromDto(dto: AbiTypeJson): AbiType { const { new_type_name, type } = dto; return new AbiType(new_type_name, type); } diff --git a/src/common/blockchain/block-content/abi/abi-variant.ts b/src/common/blockchain/abi/abi-variant.ts similarity index 67% rename from src/common/blockchain/block-content/abi/abi-variant.ts rename to src/common/blockchain/abi/abi-variant.ts index 3713fa8..b042e06 100644 --- a/src/common/blockchain/block-content/abi/abi-variant.ts +++ b/src/common/blockchain/abi/abi-variant.ts @@ -1,4 +1,4 @@ -import { AbiVariantDto } from './abi.dtos'; +import { AbiVariantJson } from './abi.dtos'; /** * @class @@ -12,19 +12,19 @@ export class AbiVariant { private constructor(public readonly name: string, public readonly types: string[]) {} /** - * @returns {AbiVariantDto} + * @returns {AbiVariantJson} */ - public toDto(): AbiVariantDto { + public toDto(): AbiVariantJson { const { name, types } = this; return { name, types }; } /** * @static - * @param {AbiVariantDto} dto + * @param {AbiVariantJson} dto * @returns {AbiVariant} */ - public static fromDto(dto: AbiVariantDto): AbiVariant { + public static fromDto(dto: AbiVariantJson): AbiVariant { const { name, types } = dto; return new AbiVariant(name, types); } diff --git a/src/common/blockchain/abi/abi.dtos.ts b/src/common/blockchain/abi/abi.dtos.ts new file mode 100644 index 0000000..e313ddb --- /dev/null +++ b/src/common/blockchain/abi/abi.dtos.ts @@ -0,0 +1,136 @@ +export type AbiActionJson = { + name: string; // The name of the action as defined in the contract + type: string; // The name of the implicit struct as described in the ABI + ricardian_contract: string; // An optional ricardian clause to associate to this action describing its intended functionality. +}; + +export type AbiJson = { + version: string; + types: AbiTypeJson[]; + structs: AbiStructJson[]; + tables: AbiTableJson[]; + actions: AbiActionJson[]; + ricardian_clauses: RicardianClauseJson[]; + abi_extensions: AbiExtensionJson[]; + error_messages: AbiErrorMessageJson[]; + variants?: AbiVariantJson[]; +}; + +export type AbiErrorMessageJson = { + error_code: number; + error_msg: string; +}; + +export type AbiVariantJson = { + name: string; + types: string[]; +}; + +export type RicardianClauseJson = { + id: string; + body: string; +}; + +export type AbiExtensionJson = { + tag: number; + value: string; +}; + +export type AbiTypeJson = { + new_type_name: string; + type: string; +}; + +export type AbiStructFieldJson = { + name: string; + type: string; +}; + +export type AbiStructJson = { + name: string; + base: string; + fields: AbiStructFieldJson[]; +}; + +export type CreateStructJson = { + name: 'create'; + base: ''; + fields: [IssuerFieldJson, MaximumSupplyFieldJson]; +}; + +export type IssueStructJson = { + name: 'issue'; + base: ''; + fields: [ToFieldJson, QuantityFieldJson, MemoFieldJson]; +}; + +export type RetireStructJson = { + name: 'retire'; + base: ''; + fields: [QuantityFieldJson, MemoFieldJson]; +}; + +export type TransfereStructJson = { + name: 'transfer'; + base: ''; + fields: [FromFieldJson, ToFieldJson, QuantityFieldJson, MemoFieldJson]; +}; + +export type CloseStructJson = { + name: 'close'; + base: ''; + fields: [SymbolFieldJson, OwnerFieldJson]; +}; + +export type FieldJson = { + name: string; + type: string; +}; + +export type OwnerFieldJson = { + name: 'owner'; + type: 'name'; +}; + +export type SymbolFieldJson = { + name: 'symbol'; + type: 'symbol'; +}; + +export type MemoFieldJson = { + name: 'memo'; + type: 'string'; +}; + +export type QuantityFieldJson = { + name: 'quantity'; + type: 'asset'; +}; + +export type ToFieldJson = { + name: 'to'; + type: 'name'; +}; + +export type FromFieldJson = { + name: 'from'; + type: 'name'; +}; + +export type IssuerFieldJson = { + name: 'issuer'; + type: 'name'; +}; + +export type MaximumSupplyFieldJson = { + name: 'maximum_supply'; + type: 'asset'; +}; + +export type AbiTableJson = { + name: string; // 'accounts' | 'stats' + type: string; // 'account' | 'currency_stats' ... Corresponds to previously defined struct + index_type: string; // 'i64' + key_names: string[]; + key_types: string[]; +}; diff --git a/src/common/blockchain/block-content/abi/abi.ts b/src/common/blockchain/abi/abi.ts similarity index 83% rename from src/common/blockchain/block-content/abi/abi.ts rename to src/common/blockchain/abi/abi.ts index c7f4af4..a2de49e 100644 --- a/src/common/blockchain/block-content/abi/abi.ts +++ b/src/common/blockchain/abi/abi.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { getTypesFromAbi } from 'eosjs/dist/eosjs-serialize'; -import { AbiDto } from './abi.dtos'; +import { AbiJson } from './abi.dtos'; import { Serialize } from 'eosjs'; import { AbiType } from './abi-type'; import { AbiStruct } from './abi-struct'; @@ -11,6 +11,7 @@ import { RicardianClause } from './ricardian-clause'; import { AbiExtension } from './abi-extension'; import { AbiErrorMessage } from './abi-error-message'; import { AbiVariant } from './abi-variant'; +import { deserialize, serialize } from 'v8'; /** * ABI entity @@ -42,14 +43,14 @@ export class Abi { public readonly errorMessages: AbiErrorMessage[], public readonly variants?: AbiVariant[] ) { - this.typesMap = getTypesFromAbi(Serialize.createInitialTypes(), this.toDto()); + this.typesMap = getTypesFromAbi(Serialize.createInitialTypes(), this.toJson()); } /** * Parse ABI entity to DTO - * @returns {AbiDto} + * @returns {AbiJson} */ - public toDto(): AbiDto { + public toJson(): AbiJson { const { version, types, @@ -62,7 +63,7 @@ export class Abi { variants, } = this; - const dto: AbiDto = { + const dto: AbiJson = { version, types: types.map(item => item.toDto()), structs: structs.map(item => item.toDto()), @@ -79,6 +80,14 @@ export class Abi { return dto; } + public toBuffer(): Buffer { + return serialize(this.toJson()); + } + + public toHex(): string { + return serialize(this.toJson()).toString('hex'); + } + public getTypesMap(): Map { return this.typesMap; } @@ -87,10 +96,10 @@ export class Abi { * Create ABI entity based on provided DTO * * @static - * @param {AbiDto} dto + * @param {AbiJson} dto * @returns {Abi} */ - public static fromDto(dto: AbiDto): Abi { + public static fromJson(dto: AbiJson): Abi { const { version, types, structs, tables } = dto; const actions = dto.actions ? dto.actions.map(dto => AbiAction.fromDto(dto)) : []; const ricardian_clauses = dto.ricardian_clauses @@ -116,4 +125,14 @@ export class Abi { variants ); } + + public static fromBuffer(buffer: Buffer): Abi { + const json = deserialize(buffer); + return Abi.fromJson(json); + } + + public static fromHex(value: string): Abi { + const buf = Buffer.from(value, 'hex'); + return Abi.fromBuffer(buf); + } } diff --git a/src/common/blockchain/block-content/abi/index.ts b/src/common/blockchain/abi/index.ts similarity index 100% rename from src/common/blockchain/block-content/abi/index.ts rename to src/common/blockchain/abi/index.ts diff --git a/src/common/blockchain/block-content/abi/ricardian-clause.ts b/src/common/blockchain/abi/ricardian-clause.ts similarity index 63% rename from src/common/blockchain/block-content/abi/ricardian-clause.ts rename to src/common/blockchain/abi/ricardian-clause.ts index efc64a0..e248fcb 100644 --- a/src/common/blockchain/block-content/abi/ricardian-clause.ts +++ b/src/common/blockchain/abi/ricardian-clause.ts @@ -1,4 +1,4 @@ -import { RicardianClauseDto } from './abi.dtos'; +import { RicardianClauseJson } from './abi.dtos'; /** * @class @@ -12,19 +12,19 @@ export class RicardianClause { private constructor(public readonly id: string, public readonly body: string) {} /** - * @returns {RicardianClauseDto} + * @returns {RicardianClauseJson} */ - public toDto(): RicardianClauseDto { + public toDto(): RicardianClauseJson { const { id, body } = this; return { id, body }; } /** * @static - * @param {RicardianClauseDto} dto + * @param {RicardianClauseJson} dto * @returns {RicardianClause} */ - public static fromDto(dto: RicardianClauseDto): RicardianClause { + public static fromDto(dto: RicardianClauseJson): RicardianClause { const { id, body } = dto; return new RicardianClause(id, body); } diff --git a/src/common/blockchain/block-content/abi/abi.dtos.ts b/src/common/blockchain/block-content/abi/abi.dtos.ts deleted file mode 100644 index 81bb4ab..0000000 --- a/src/common/blockchain/block-content/abi/abi.dtos.ts +++ /dev/null @@ -1,136 +0,0 @@ -export type AbiActionDto = { - name: string; // The name of the action as defined in the contract - type: string; // The name of the implicit struct as described in the ABI - ricardian_contract: string; // An optional ricardian clause to associate to this action describing its intended functionality. -}; - -export type AbiDto = { - version: string; - types: AbiTypeDto[]; - structs: AbiStructDto[]; - tables: AbiTableDto[]; - actions: AbiActionDto[]; - ricardian_clauses: RicardianClauseDto[]; - abi_extensions: AbiExtensionDto[]; - error_messages: AbiErrorMessageDto[]; - variants?: AbiVariantDto[]; -}; - -export type AbiErrorMessageDto = { - error_code: number; - error_msg: string; -}; - -export type AbiVariantDto = { - name: string; - types: string[]; -}; - -export type RicardianClauseDto = { - id: string; - body: string; -}; - -export type AbiExtensionDto = { - tag: number; - value: string; -}; - -export type AbiTypeDto = { - new_type_name: string; - type: string; -}; - -export type AbiStructFieldDto = { - name: string; - type: string; -}; - -export type AbiStructDto = { - name: string; - base: string; - fields: AbiStructFieldDto[]; -}; - -export type CreateStructDto = { - name: 'create'; - base: ''; - fields: [IssuerFieldDto, MaximumSupplyFieldDto]; -}; - -export type IssueStructDto = { - name: 'issue'; - base: ''; - fields: [ToFieldDto, QuantityFieldDto, MemoFieldDto]; -}; - -export type RetireStructDto = { - name: 'retire'; - base: ''; - fields: [QuantityFieldDto, MemoFieldDto]; -}; - -export type TransfereStructDto = { - name: 'transfer'; - base: ''; - fields: [FromFieldDto, ToFieldDto, QuantityFieldDto, MemoFieldDto]; -}; - -export type CloseStructDto = { - name: 'close'; - base: ''; - fields: [SymbolFieldDto, OwnerFieldDto]; -}; - -export type FieldDto = { - name: string; - type: string; -}; - -export type OwnerFieldDto = { - name: 'owner'; - type: 'name'; -}; - -export type SymbolFieldDto = { - name: 'symbol'; - type: 'symbol'; -}; - -export type MemoFieldDto = { - name: 'memo'; - type: 'string'; -}; - -export type QuantityFieldDto = { - name: 'quantity'; - type: 'asset'; -}; - -export type ToFieldDto = { - name: 'to'; - type: 'name'; -}; - -export type FromFieldDto = { - name: 'from'; - type: 'name'; -}; - -export type IssuerFieldDto = { - name: 'issuer'; - type: 'name'; -}; - -export type MaximumSupplyFieldDto = { - name: 'maximum_supply'; - type: 'asset'; -}; - -export type AbiTableDto = { - name: string; // 'accounts' | 'stats' - type: string; // 'account' | 'currency_stats' ... Corresponds to previously defined struct - index_type: string; // 'i64' - key_names: string[]; - key_types: string[]; -}; diff --git a/src/common/blockchain/block-content/block/index.ts b/src/common/blockchain/block-content/block/index.ts deleted file mode 100644 index 6728bed..0000000 --- a/src/common/blockchain/block-content/block/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './block'; -export * from './block.dtos'; \ No newline at end of file diff --git a/src/common/blockchain/block-reader/__tests__/block-reader.source.unit.test.ts b/src/common/blockchain/block-reader/__tests__/block-reader.source.unit.test.ts deleted file mode 100644 index 64fbab8..0000000 --- a/src/common/blockchain/block-reader/__tests__/block-reader.source.unit.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { BlockReaderConnectionState } from "../block-reader.enums"; -import { BlockReaderSource } from "../block-reader.source"; - - -const webSocketMock = { - on: jest.fn(), - once: jest.fn((type, callback) => { - callback(true); - }), - close: jest.fn(), - send: jest.fn(), - removeAllListeners: jest.fn(), -}; - -jest.mock('ws', () => jest.fn().mockImplementation(() => webSocketMock)); - -describe('BlockReaderSource Unit tests', () => { - it('"updateConnectionState" should return a handler assigned to the connection state', () => { - const source = new BlockReaderSource({} as any); - const handler = jest.fn(); - source.addConnectionStateHandler(BlockReaderConnectionState.Connected, handler); - - (source as any).updateConnectionState(BlockReaderConnectionState.Connected); - - expect(handler).toBeCalled(); - }); - - it('"getNextEndpoint" should return first endpoint form the list', () => { - const source = new BlockReaderSource({ endpoints: ['foo', 'bar'] } as any); - const endpoint = (source as any).getNextEndpoint(); - - expect(endpoint).toEqual('foo'); - }); - - it('"getNextEndpoint" should return last endpoint form the list', () => { - const endpoints = ['foo', 'bar']; - const source = new BlockReaderSource({ endpoints } as any); - let endpoint; - - for (let i = 0; i < endpoints.length; i++) { - endpoint = (source as any).getNextEndpoint(); - } - - expect(endpoint).toEqual('bar'); - }); - - it('"getNextEndpoint" should return first endpoint form the list when it went through the entire list', () => { - const source = new BlockReaderSource({ endpoints: ['foo', 'bar'] } as any); - (source as any).getNextEndpoint(); - (source as any).getNextEndpoint(); - const endpoint = (source as any).getNextEndpoint(); - - expect(endpoint).toEqual('foo'); - }); - - it('"onError" should set error handler', () => { - const source = new BlockReaderSource({} as any); - source.onError(jest.fn()); - - expect((source as any).errorHandler).toBeTruthy(); - }); - - it('"onMessage" should set message handler', () => { - const source = new BlockReaderSource({} as any); - source.onMessage(jest.fn()); - - expect((source as any).messageHandler).toBeTruthy(); - }); - - it('"addConnectionStateHandler" should log warning if there is already a handler assigned to the state', () => { - const source = new BlockReaderSource({} as any); - const warnMock = jest.spyOn(console, 'warn'); - - source.addConnectionStateHandler(BlockReaderConnectionState.Connected, jest.fn()); - source.addConnectionStateHandler(BlockReaderConnectionState.Connected, jest.fn()); - - expect(warnMock).toBeCalled(); - - warnMock.mockClear(); - }); - - it('"addConnectionStateHandler" should assign a handler to the state', () => { - const source = new BlockReaderSource({} as any); - - source.addConnectionStateHandler(BlockReaderConnectionState.Connected, jest.fn()); - - expect( - (source as any).connectionChangeHandlers.has(BlockReaderConnectionState.Connected) - ).toBeTruthy(); - }); - - it('"isConnected" should return true if source is connected', () => { - const source = new BlockReaderSource({} as any); - (source as any).connectionState = BlockReaderConnectionState.Connected; - - expect(source.isConnected).toBeTruthy(); - }); - - it('"isConnected" should return false if source is not connected', () => { - const source = new BlockReaderSource({} as any); - (source as any).connectionState = BlockReaderConnectionState.Idle; - - expect(source.isConnected).toBeFalsy(); - }); - - it('"connect" should change connection status to "connecting" and then after successful connection to "connected"', async () => { - const source = new BlockReaderSource({} as any); - const updateConnectionStateMock = jest.fn(); - - (source as any).errorHandler = jest.fn(); - (source as any).getNextEndpoint = jest.fn(); - (source as any).updateConnectionState = updateConnectionStateMock; - (source as any).waitUntilConnectionIsOpen = jest.fn(); - (source as any).receiveAbi = jest.fn().mockResolvedValue(''); - - await source.connect(); - - expect(updateConnectionStateMock).toBeCalledTimes(2); - }); - - it('"connect" should call error handler on any error', async () => { - const source = new BlockReaderSource({} as any); - - (source as any).errorHandler = jest.fn(); - (source as any).getNextEndpoint = jest.fn().mockImplementation(() => { - throw new Error(); - }); - - await source.connect(); - - expect((source as any).errorHandler).toBeCalled(); - }); - - it('"connect" should wait until connection is open and receive first message as ABI', async () => { - const source = new BlockReaderSource({} as any); - const updateConnectionStateMock = jest.fn(); - - (source as any).errorHandler = jest.fn(); - (source as any).getNextEndpoint = jest.fn(); - (source as any).updateConnectionState = updateConnectionStateMock; - (source as any).waitUntilConnectionIsOpen = jest.fn(); - (source as any).receiveAbi = jest.fn().mockResolvedValue(''); - - await source.connect(); - - expect((source as any).waitUntilConnectionIsOpen).toBeCalled(); - expect((source as any).receiveAbi).toBeCalled(); - }); - - it('"disconnect" should change connection status to "disconnecting" and then after successful disconnection to "idle"', async () => { - const source = new BlockReaderSource({} as any); - const updateConnectionStateMock = jest.fn(); - - (source as any).connectionState = BlockReaderConnectionState.Connected; - (source as any).client = webSocketMock; - (source as any).errorHandler = jest.fn(); - (source as any).updateConnectionState = updateConnectionStateMock; - (source as any).waitUntilConnectionIsClosed = jest.fn(); - - await source.disconnect(); - - expect(webSocketMock.close).toBeCalled(); - expect((source as any).client).toBeNull(); - expect(updateConnectionStateMock).toBeCalledTimes(2); - }); - - it('"disconnect" should call error handler on any error', async () => { - const source = new BlockReaderSource({} as any); - - (source as any).connectionState = BlockReaderConnectionState.Connected; - (source as any).errorHandler = jest.fn(); - (source as any).client = webSocketMock; - (source as any).client.close.mockImplementation(() => { - throw new Error(); - }); - - await source.disconnect(); - - expect((source as any).errorHandler).toBeCalled(); - }); - - it('"send" should call client.send', async () => { - const source = new BlockReaderSource({} as any); - (source as any).client = webSocketMock; - - await source.send(new Uint8Array()); - - expect((source as any).client.send).toBeCalled(); - }); - - it('"waitUntilConnectionIsOpen" should resolve a promise on "open" handler', async () => { - const source = new BlockReaderSource({} as any); - (source as any).client = webSocketMock; - - const result = await (source as any).waitUntilConnectionIsOpen(); - - expect(result).toBeTruthy(); - }); - it('"waitUntilConnectionIsClosed" should resolve a promise on "close" handler', async () => { - const source = new BlockReaderSource({} as any); - (source as any).client = webSocketMock; - - const result = await (source as any).waitUntilConnectionIsClosed(); - - expect(result).toBeTruthy(); - }); - it('"receiveAbi" should resolve a promise once on "message" handler', async () => { - const source = new BlockReaderSource({} as any); - (source as any).client = webSocketMock; - - const result = await (source as any).receiveAbi(); - - expect(result).toBeTruthy(); - }); -}); diff --git a/src/common/blockchain/block-reader/__tests__/block-reader.utils.unit.test.ts b/src/common/blockchain/block-reader/__tests__/block-reader.utils.unit.test.ts deleted file mode 100644 index ccabec8..0000000 --- a/src/common/blockchain/block-reader/__tests__/block-reader.utils.unit.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { Serialize } from 'eosjs'; -import { deserializeMessage, serializeMessage } from '../block-reader.utils'; - -jest.mock('eosjs'); - -const SerialBufferMock = Serialize.SerialBuffer as jest.MockedClass< - typeof Serialize.SerialBuffer ->; - -const type = { - name: 'foo', - aliasOfName: 'foo', - arrayOf: {}, - optionalOf: {}, - baseName: 'foo', - base: {}, - fields: [], - serialize: jest.fn(), - deserialize: jest.fn(), -}; - -const typesByName = new Map([['foo', type]]); - -describe('State History Service Unit tests', () => { - it('"serializeMessage" should return buffer as Uint8Array', () => { - SerialBufferMock.prototype.asUint8Array.mockReturnValue(Uint8Array.from([])); - (Serialize.getType as any) = jest.fn().mockReturnValue(type); - - const result = serializeMessage('foo', '', typesByName as any); - expect(result).toBeInstanceOf(Uint8Array); - }); - - it('"deserializeMessage" should return deserialized data', () => { - const data = { versions: '1.0' }; - const readPos = 18; - const encoded = new TextEncoder().encode(JSON.stringify(data)); - - type.deserialize.mockReturnValue(data); - SerialBufferMock.prototype.asUint8Array.mockReturnValue(encoded); - SerialBufferMock.prototype.readPos = readPos; - (Serialize.getType as any) = jest.fn().mockReturnValue(type); - - const result = deserializeMessage('foo', encoded, typesByName as any); - expect(result).toEqual(data); - }); -}); diff --git a/src/common/blockchain/block-reader/block-reader.config.ts b/src/common/blockchain/block-reader/block-reader.config.ts index 90f6809..61745be 100644 --- a/src/common/blockchain/block-reader/block-reader.config.ts +++ b/src/common/blockchain/block-reader/block-reader.config.ts @@ -1,6 +1,10 @@ +import { MongoConfig } from '@alien-worlds/api-core'; + export type BlockReaderConfig = { + mongo: MongoConfig; endpoints: string[]; reconnectInterval?: number; shouldFetchDeltas?: boolean; shouldFetchTraces?: boolean; + shouldFetchBlock?: boolean; }; diff --git a/src/common/blockchain/block-reader/block-reader.dtos.ts b/src/common/blockchain/block-reader/block-reader.dtos.ts deleted file mode 100644 index 6a44e31..0000000 --- a/src/common/blockchain/block-reader/block-reader.dtos.ts +++ /dev/null @@ -1,14 +0,0 @@ -export type BlockNumberWithIdDto = { - block_num: number; - block_id: string; -}; - -export type GetBlocksResultDto = { - head: BlockNumberWithIdDto; - this_block: BlockNumberWithIdDto; - last_irreversible: BlockNumberWithIdDto; - prev_block: BlockNumberWithIdDto; - block: Uint8Array; - traces: Uint8Array; - deltas: Uint8Array; -}; diff --git a/src/common/blockchain/block-reader/block-reader.message.ts b/src/common/blockchain/block-reader/block-reader.message.ts new file mode 100644 index 0000000..4c63146 --- /dev/null +++ b/src/common/blockchain/block-reader/block-reader.message.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import { Abi } from '../abi'; +import { GetBlocksResultMessageContent } from './block-reader.types'; +import { deserializeMessage } from './block-reader.utils'; +import { Block } from './block/block'; +import { BlockJson } from './block/block.types'; + +export class BlockReaderMessage { + public static readonly version = 'v0'; + + private static isGetBlocksResultPongMessage(data: GetBlocksResultMessageContent): boolean { + return ( + typeof data.head === 'object' && + typeof data.last_irreversible === 'object' && + !data.prev_block && + !data.this_block && + !data.block && + !data.traces && + !data.deltas + ); + } + + public static create( + dto: Uint8Array, + abi: Abi + ) { + const result = deserializeMessage('result', dto, abi.getTypesMap()); + const [resultType, resultJson]: [string, MessageContentType] = result || []; + + if (resultType) { + if (resultType === `get_blocks_result_${this.version}`) { + if ( + BlockReaderMessage.isGetBlocksResultPongMessage( + resultJson + ) + ) { + return new BlockReaderMessage(resultType, null, true); + } + + (resultJson).abi_version = abi.version; + return new BlockReaderMessage( + resultType, + Block.fromJson(resultJson) + ); + } + } + + return null; + } + + private constructor( + public readonly type: string, + public readonly content: MessageContentType, + public readonly isPongMessage = false + ) {} +} diff --git a/src/common/blockchain/block-reader/models/get-blocks.request.ts b/src/common/blockchain/block-reader/block-reader.requests.ts similarity index 71% rename from src/common/blockchain/block-reader/models/get-blocks.request.ts rename to src/common/blockchain/block-reader/block-reader.requests.ts index 49cbcea..38c334c 100644 --- a/src/common/blockchain/block-reader/models/get-blocks.request.ts +++ b/src/common/blockchain/block-reader/block-reader.requests.ts @@ -1,6 +1,6 @@ import { Serialize } from 'eosjs'; -import { BlockReaderOptions } from '../block-reader.types'; -import { serializeMessage } from '../block-reader.utils'; +import { BlockReaderOptions } from './block-reader.types'; +import { serializeMessage } from './block-reader.utils'; export class GetBlocksRequest { public readonly version = 'v0'; @@ -50,3 +50,20 @@ export class GetBlocksRequest { ); } } + +export class GetBlocksAckRequest { + public readonly version = 'v0'; + + constructor( + public readonly messagesCount: number, + public readonly types: Map + ) {} + + public toUint8Array() { + return serializeMessage( + 'request', + [`get_blocks_ack_request_${this.version}`, { num_messages: this.messagesCount }], + this.types + ); + } +} diff --git a/src/common/blockchain/block-reader/block-reader.source.ts b/src/common/blockchain/block-reader/block-reader.source.ts index 226877c..fb0fb37 100644 --- a/src/common/blockchain/block-reader/block-reader.source.ts +++ b/src/common/blockchain/block-reader/block-reader.source.ts @@ -46,26 +46,18 @@ export class BlockReaderSource { private waitUntilConnectionIsOpen() { log(`BlockReader plugin connecting to: ${this.endpoint}`); - return new Promise((resolve, reject) => { + return new Promise(resolve => { this.client.once('open', () => { log(`BlockReader plugin connection open.`); resolve(true); }); - this.client.once('close', code => { - log(`BlockReader plugin connection closed with code #${code}.`); - reject(code); - }); }); } - private waitUntilConnectionIsClosed() { - log(`BlockReader plugin closing connection...`); - return new Promise(resolve => { - this.client.once('close', code => { - log(`BlockReader plugin connection closed with code #${code}.`); - resolve(code); - }); - }); + private async onConnectionClosed(code: number) { + this.client = null; + log(`BlockReader plugin connection closed with code #${code}.`); + await this.updateConnectionState(BlockReaderConnectionState.Idle); } private receiveAbi() { @@ -104,6 +96,7 @@ export class BlockReaderSource { this.client = new WebSocket(this.endpoint, { perMessageDeflate: false, }); + this.client.on('close', code => this.onConnectionClosed(code)); this.client.on('error', error => this.errorHandler(error)); await this.waitUntilConnectionIsOpen(); // receive ABI - first message from WS is always ABI @@ -130,9 +123,6 @@ export class BlockReaderSource { await this.updateConnectionState(BlockReaderConnectionState.Disconnecting); this.client.removeAllListeners(); this.client.close(); - await this.waitUntilConnectionIsClosed(); - this.client = null; - await this.updateConnectionState(BlockReaderConnectionState.Idle); } catch (error) { this.errorHandler(error); } diff --git a/src/common/blockchain/block-reader/block-reader.ts b/src/common/blockchain/block-reader/block-reader.ts index f22bc29..412f17e 100644 --- a/src/common/blockchain/block-reader/block-reader.ts +++ b/src/common/blockchain/block-reader/block-reader.ts @@ -1,61 +1,45 @@ /* eslint-disable @typescript-eslint/restrict-template-expressions */ -import { log } from '@alien-worlds/api-core'; -import { Abi, AbiDto } from '../block-content'; +import { MongoSource, log } from '@alien-worlds/api-core'; +import { BlockReaderConfig } from './block-reader.config'; import { BlockReaderConnectionState } from './block-reader.enums'; import { AbiNotFoundError, MissingHandlersError, - UnhandledBlockRequestError, UnhandledMessageError, UnhandledMessageTypeError, } from './block-reader.errors'; import { BlockReaderSource } from './block-reader.source'; import { BlockReaderOptions, ConnectionChangeHandlerOptions } from './block-reader.types'; -import { BlockReaderMessage } from './models/block-reader.message'; -import { GetBlocksAckRequest } from './models/get-blocks-ack.request'; -import { GetBlocksRequest } from './models/get-blocks.request'; -import { ReceivedBlock } from './models/received-block'; +import { BlockReaderMessage } from './block-reader.message'; +import { GetBlocksAckRequest, GetBlocksRequest } from './block-reader.requests'; +import { Block } from './block/block'; +import { ShipAbiSource } from '../../ship/ship-abi.source'; +import { Abi, AbiJson } from '../abi'; -export abstract class BlockReader { - public abstract readOneBlock(block: bigint, options?: BlockReaderOptions): void; +export class BlockReader { + public static async create(config: BlockReaderConfig): Promise { + const mongoSource = await MongoSource.create(config.mongo); + const shipAbiSource = new ShipAbiSource(mongoSource); + const source = new BlockReaderSource(config); + source.onError(error => log(error)); - public abstract readBlocks( - startBlock: bigint, - endBlock: bigint, - options?: BlockReaderOptions - ): void; - public abstract connect(): Promise; - public abstract disconnect(): Promise; - public abstract onReceivedBlock( - handler: (content: ReceivedBlock) => void | Promise - ); - public abstract onComplete( - handler: (startBlock?: bigint, endBlock?: bigint) => void | Promise - ); - public abstract onError(handler: (error: Error) => void | Promise); - public abstract onWarning(handler: (...args: unknown[]) => void | Promise); - public abstract hasFinished(): boolean; -} - -/* eslint-disable @typescript-eslint/no-unsafe-argument */ + return new BlockReader(source, shipAbiSource); + } -export class BlockReaderService implements BlockReader { private errorHandler: (error: Error) => void; private warningHandler: (...args: unknown[]) => void; - private receivedBlockHandler: (content: ReceivedBlock) => Promise; + private receivedBlockHandler: (content: Block) => Promise | void; private blockRangeCompleteHandler: ( startBlock: bigint, endBlock: bigint ) => Promise; - private blockRangeRequest: GetBlocksRequest; - private abi: Abi; - - constructor(private source: BlockReaderSource) { - this.source.onMessage(message => { - this.onMessage(message).catch((error: Error) => { - this.handleError(error); - }); - }); + private _blockRangeRequest: GetBlocksRequest; + private _abi: Abi; + private _paused = false; + private isLastBlock = false; + + constructor(private source: BlockReaderSource, private shipAbi: ShipAbiSource) { + this.source.onMessage(message => this.onMessage(message)); this.source.onError(error => { this.handleError(error); }); @@ -67,21 +51,33 @@ export class BlockReaderService implements BlockReader { ); } - private onConnected({ data }: ConnectionChangeHandlerOptions) { + private async onConnected({ data }: ConnectionChangeHandlerOptions) { log(`BlockReader plugin connected`); - this.abi = Abi.fromDto(JSON.parse(data) as AbiDto); + const abi = Abi.fromJson(JSON.parse(data) as AbiJson); + if (abi) { + const result = await this.shipAbi.getAbi(abi.version); + + if (result.isFailure) { + await this.shipAbi.updateAbi(abi); + } + this._abi = abi; + } } private onDisconnected({ previousState }: ConnectionChangeHandlerOptions) { log(`BlockReader plugin disconnected`); if (previousState === BlockReaderConnectionState.Disconnecting) { - this.abi = null; + this._abi = null; } this.connect(); } - public async onMessage(dto: Uint8Array): Promise { + public get abi(): Abi { + return this._abi; + } + + public onMessage(dto: Uint8Array): Promise { const { abi } = this; if (!abi) { @@ -89,19 +85,24 @@ export class BlockReaderService implements BlockReader { return; } - const message = BlockReaderMessage.create(dto, abi.getTypesMap()); + const message = BlockReaderMessage.create(dto, abi); - if (message) { + if (message && message.isPongMessage === false) { this.handleBlocksResultContent(message.content); - } else { + } else if (!message) { this.handleError(new UnhandledMessageTypeError(message.type)); } } - private async handleBlocksResultContent(result: ReceivedBlock) { + private async handleBlocksResultContent(result: Block) { const { thisBlock } = result; const { abi } = this; + // skip any extra result messages + if (this.isLastBlock) { + return; + } + if (!abi) { this.handleError(new AbiNotFoundError()); return; @@ -110,11 +111,11 @@ export class BlockReaderService implements BlockReader { try { if (thisBlock) { const { - blockRangeRequest: { startBlock, endBlock }, + _blockRangeRequest: { startBlock, endBlock }, } = this; - const isLast = thisBlock.blockNumber === endBlock - 1n; + this.isLastBlock = thisBlock.blockNumber === endBlock - 1n; - if (isLast) { + if (this.isLastBlock) { await this.receivedBlockHandler(result); this.blockRangeCompleteHandler(startBlock, endBlock); } else { @@ -123,7 +124,7 @@ export class BlockReaderService implements BlockReader { // processing the full range, it will send messages containing only head. // After the block has been processed, the connection should be closed so // there is no need to ack request. - if (this.source.isConnected) { + if (this.source.isConnected && this._paused === false) { // Acknowledge a request so that source can send next one. this.source.send( new GetBlocksAckRequest(1, abi.getTypesMap()).toUint8Array() @@ -133,7 +134,6 @@ export class BlockReaderService implements BlockReader { } else { this.handleWarning(`the received message does not contain this_block`); } - } catch (error) { this.handleError(new UnhandledMessageError(result, error)); } @@ -152,7 +152,7 @@ export class BlockReaderService implements BlockReader { } public async connect(): Promise { - if (!this.source.isConnected) { + if (this.source.isConnected === false) { await this.source.connect(); } else { log(`Service already connected`); @@ -167,6 +167,19 @@ export class BlockReaderService implements BlockReader { } } + public pause(): void { + if (this._paused === false) { + this._paused = true; + } + } + + public resume(): void { + if (this._paused && !this.isLastBlock) { + this._paused = false; + this.source.send(new GetBlocksAckRequest(1, this.abi.getTypesMap()).toUint8Array()); + } + } + public readBlocks( startBlock: bigint, endBlock: bigint, @@ -191,29 +204,28 @@ export class BlockReaderService implements BlockReader { shouldFetchTraces: true, }; + this.isLastBlock = false; + this.resume(); + const { abi, receivedBlockHandler, source } = this; if (!receivedBlockHandler) { throw new MissingHandlersError(); } - // still processing block range request? - if (this.blockRangeRequest) { - throw new UnhandledBlockRequestError(startBlock, endBlock); - } if (!abi) { throw new AbiNotFoundError(); } - this.blockRangeRequest = GetBlocksRequest.create( + this._blockRangeRequest = GetBlocksRequest.create( startBlock, endBlock, requestOptions, abi.getTypesMap() ); - source.send(this.blockRangeRequest.toUint8Array()); + source.send(this._blockRangeRequest.toUint8Array()); } - public onReceivedBlock(handler: (content: ReceivedBlock) => Promise) { + public onReceivedBlock(handler: (content: Block) => Promise | void) { this.receivedBlockHandler = handler; } @@ -228,8 +240,4 @@ export class BlockReaderService implements BlockReader { public onWarning(handler: (...args: unknown[]) => void) { this.warningHandler = handler; } - - public hasFinished(): boolean { - return this.blockRangeRequest === null; - } } diff --git a/src/common/blockchain/block-reader/block-reader.types.ts b/src/common/blockchain/block-reader/block-reader.types.ts index 3948722..230a818 100644 --- a/src/common/blockchain/block-reader/block-reader.types.ts +++ b/src/common/blockchain/block-reader/block-reader.types.ts @@ -13,4 +13,28 @@ export type ConnectionChangeHandler = ( export type BlockReaderOptions = { shouldFetchDeltas?: boolean; shouldFetchTraces?: boolean; + shouldFetchBlock?: boolean; +}; + +export type GetBlocksResultMessageContent = { + head?: { + block_num: number; + block_id: string; + }; + last_irreversible?: { + block_num: number; + block_id: string; + }; + this_block?: { + block_num: number; + block_id: string; + }; + prev_block?: { + block_num: number; + block_id: string; + }; + block?: Uint8Array; + traces?: Uint8Array; + deltas?: Uint8Array; + [key: string]: unknown; }; diff --git a/src/common/blockchain/block-reader/block-reader.utils.ts b/src/common/blockchain/block-reader/block-reader.utils.ts index f24368b..f990211 100644 --- a/src/common/blockchain/block-reader/block-reader.utils.ts +++ b/src/common/blockchain/block-reader/block-reader.utils.ts @@ -1,22 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { log } from '@alien-worlds/api-core'; import { Serialize } from 'eosjs'; import { TextDecoder, TextEncoder } from 'text-encoding'; -import { BlockReader, BlockReaderService } from './block-reader'; -import { BlockReaderConfig } from './block-reader.config'; -import { BlockReaderSource } from './block-reader.source'; - -export const setupBlockReader = async ( - config: BlockReaderConfig -): Promise => { - const source = new BlockReaderSource(config); - source.onError(error => log(error)); - const blockReader = new BlockReaderService(source); - await blockReader.connect(); - - return blockReader; -}; export const serializeMessage = ( type: string, diff --git a/src/common/blockchain/block-reader/block/block.ts b/src/common/blockchain/block-reader/block/block.ts new file mode 100644 index 0000000..af6086f --- /dev/null +++ b/src/common/blockchain/block-reader/block/block.ts @@ -0,0 +1,145 @@ +import { MongoDB, parseToBigInt } from '@alien-worlds/api-core'; +import { + BlockDocument, + BlockJson, + BlockNumberWithIdDocument, + BlockNumberWithIdJson, +} from './block.types'; + +export class BlockNumberWithId { + public static fromJson(dto: BlockNumberWithIdJson) { + const { block_id, block_num } = dto; + return new BlockNumberWithId(parseToBigInt(block_num), block_id); + } + + public static fromDocument(dto: BlockNumberWithIdDocument) { + const { block_id, block_num } = dto; + return new BlockNumberWithId(parseToBigInt(block_num), block_id); + } + + private constructor( + public readonly blockNumber: bigint, + public readonly blockId: string + ) {} + + public toJson() { + return { + block_num: this.blockNumber.toString(), + block_id: this.blockId, + }; + } + + public toDocument() { + return { + block_num: MongoDB.Long.fromBigInt(this.blockNumber), + block_id: this.blockId, + }; + } +} + +export class Block { + public static fromJson(json: BlockJson): Block { + const { block, traces, deltas, abi_version } = json; + const head = BlockNumberWithId.fromJson(json.head); + const lastIrreversible = BlockNumberWithId.fromJson(json.last_irreversible); + const prevBlock = BlockNumberWithId.fromJson(json.prev_block); + const thisBlock = BlockNumberWithId.fromJson(json.this_block); + + return new Block( + head, + lastIrreversible, + prevBlock, + thisBlock, + block, + traces, + deltas, + abi_version + ); + } + + public static fromDocument(content: BlockDocument): Block { + const { block, traces, deltas, _id, abi_version } = content; + const head = BlockNumberWithId.fromDocument(content.head); + const lastIrreversible = BlockNumberWithId.fromDocument(content.last_irreversible); + const prevBlock = BlockNumberWithId.fromDocument(content.prev_block); + const thisBlock = BlockNumberWithId.fromDocument(content.this_block); + + return new Block( + head, + lastIrreversible, + prevBlock, + thisBlock, + block.buffer, + traces.buffer, + deltas.buffer, + abi_version, + _id.toString() + ); + } + + private constructor( + public readonly head: BlockNumberWithId, + public readonly lastIrreversible: BlockNumberWithId, + public readonly prevBlock: BlockNumberWithId, + public readonly thisBlock: BlockNumberWithId, + public readonly block: Uint8Array, + public readonly traces: Uint8Array, + public readonly deltas: Uint8Array, + public readonly abiVersion?: string, + public readonly id?: string + ) {} + + public toJson(): BlockJson { + const { head, thisBlock, prevBlock, lastIrreversible, block, traces, deltas, abiVersion } = this; + + const json: BlockJson = { + head: head.toJson(), + this_block: thisBlock.toJson(), + prev_block: prevBlock.toJson(), + last_irreversible: lastIrreversible.toJson(), + block, + traces, + deltas, + }; + + if (abiVersion) { + json.abi_version = abiVersion; + } + + return json; + } + + public toDocument(): BlockDocument { + const { + head, + thisBlock, + prevBlock, + lastIrreversible, + block, + traces, + deltas, + id, + abiVersion, + } = this; + + const document: BlockDocument = { + head: head.toDocument(), + this_block: thisBlock.toDocument(), + prev_block: prevBlock.toDocument(), + last_irreversible: lastIrreversible.toDocument(), + block: new MongoDB.Binary(block), + traces: new MongoDB.Binary(traces), + deltas: new MongoDB.Binary(deltas), + }; + + if (abiVersion) { + document.abi_version = abiVersion; + } + + if (id) { + document._id = new MongoDB.ObjectId(id); + } + + return document; + } +} diff --git a/src/common/blockchain/block-reader/block/block.types.ts b/src/common/blockchain/block-reader/block/block.types.ts new file mode 100644 index 0000000..356c5b0 --- /dev/null +++ b/src/common/blockchain/block-reader/block/block.types.ts @@ -0,0 +1,35 @@ +import { MongoDB } from '@alien-worlds/api-core'; + +export type BlockNumberWithIdJson = { + block_num: string; + block_id: string; +}; + +export type BlockJson = { + head?: BlockNumberWithIdJson; + this_block?: BlockNumberWithIdJson; + last_irreversible?: BlockNumberWithIdJson; + prev_block?: BlockNumberWithIdJson; + block?: Uint8Array; + traces?: Uint8Array; + deltas?: Uint8Array; + abi_version?: string; +}; + +export type BlockDocument = { + head?: BlockNumberWithIdDocument; + this_block?: BlockNumberWithIdDocument; + last_irreversible?: BlockNumberWithIdDocument; + prev_block?: BlockNumberWithIdDocument; + block?: MongoDB.Binary; + traces?: MongoDB.Binary; + deltas?: MongoDB.Binary; + _id?: MongoDB.ObjectId; + abi_version?: string; + [key: string]: unknown; +}; + +export type BlockNumberWithIdDocument = { + block_num?: MongoDB.Long; + block_id?: string; +}; diff --git a/src/common/blockchain/block-reader/block/index.ts b/src/common/blockchain/block-reader/block/index.ts new file mode 100644 index 0000000..788a4b9 --- /dev/null +++ b/src/common/blockchain/block-reader/block/index.ts @@ -0,0 +1,2 @@ +export * from './block'; +export * from './block.types'; diff --git a/src/common/blockchain/block-reader/index.ts b/src/common/blockchain/block-reader/index.ts index 69ac401..6475d7c 100644 --- a/src/common/blockchain/block-reader/index.ts +++ b/src/common/blockchain/block-reader/index.ts @@ -1,9 +1,9 @@ -export * from './block-reader'; export * from './block-reader.config'; -export * from './block-reader.dtos'; export * from './block-reader.enums'; export * from './block-reader.errors'; +export * from './block-reader.message'; +export * from './block-reader.requests'; export * from './block-reader.source'; +export * from './block-reader'; export * from './block-reader.types'; export * from './block-reader.utils'; -export * from './models'; diff --git a/src/common/blockchain/block-reader/models/__tests__/block-reader.message.unit.test.ts b/src/common/blockchain/block-reader/models/__tests__/block-reader.message.unit.test.ts deleted file mode 100644 index e3ee254..0000000 --- a/src/common/blockchain/block-reader/models/__tests__/block-reader.message.unit.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { ReceivedBlock } from '../received-block'; -import { BlockReaderMessage } from '../block-reader.message'; -import { deserializeMessage } from '../../block-reader.utils'; - -jest.mock('eosjs/dist/eosjs-serialize'); -jest.mock( - '../../block-reader.utils', - jest.fn(() => ({ - deserializeMessage: jest.fn(() => ['get_status_result_v0', {}]), - })) -); - -describe('BlockReaderMessage Unit tests', () => { - it('"create" should create BlockReaderMessage entity based on given DTO', async () => { - ReceivedBlock.create = jest.fn().mockImplementation(); - - const entity = BlockReaderMessage.create(Uint8Array.from([]), new Map()); - - expect(entity).toBeInstanceOf(BlockReaderMessage); - expect(deserializeMessage).toBeCalled(); - }); -}); diff --git a/src/common/blockchain/block-reader/models/__tests__/get-blocks-ack.request.unit.test.ts b/src/common/blockchain/block-reader/models/__tests__/get-blocks-ack.request.unit.test.ts deleted file mode 100644 index a73e2a6..0000000 --- a/src/common/blockchain/block-reader/models/__tests__/get-blocks-ack.request.unit.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { serializeMessage } from '../../block-reader.utils'; -import { GetBlocksAckRequest } from '../get-blocks-ack.request'; - -jest.mock('eosjs/dist/eosjs-serialize'); -jest.mock('../../block-reader.utils'); - -describe('GetBlocksAckRequest Unit tests', () => { - it('"create" should create GetBlocksAckRequest entity based on given DTO', async () => { - const entity = new GetBlocksAckRequest(1, new Map()); - expect(entity).toBeInstanceOf(GetBlocksAckRequest); - }); - - it('"toUint8Array" should call serializeMessage util', async () => { - const entity = new GetBlocksAckRequest(1, new Map()); - entity.toUint8Array(); - expect(serializeMessage).toBeCalled(); - }); -}); diff --git a/src/common/blockchain/block-reader/models/__tests__/get-blocks.request.unit.test.ts b/src/common/blockchain/block-reader/models/__tests__/get-blocks.request.unit.test.ts deleted file mode 100644 index 670b9b5..0000000 --- a/src/common/blockchain/block-reader/models/__tests__/get-blocks.request.unit.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { serializeMessage } from '../../block-reader.utils'; -import { GetBlocksRequest } from '../get-blocks.request'; - -jest.mock('eosjs/dist/eosjs-serialize'); -jest.mock('../../block-reader.utils'); - -describe('GetBlocksRequest Unit tests', () => { - it('"create" should create GetBlocksRequest entity based on given DTO', async () => { - const entity = GetBlocksRequest.create( - 0n, 1n, - { - shouldFetchDeltas: true, - shouldFetchTraces: true, - }, - new Map() - ); - expect(entity).toBeInstanceOf(GetBlocksRequest); - }); - - it('"toUint8Array" should call serializeMessage util', async () => { - const entity = GetBlocksRequest.create( - 0n, 1n, - { - shouldFetchDeltas: true, - shouldFetchTraces: true, - }, - new Map() - ); - entity.toUint8Array(); - expect(serializeMessage).toBeCalled(); - }); -}); diff --git a/src/common/blockchain/block-reader/models/__tests__/get-blocks.result.unit.test.ts b/src/common/blockchain/block-reader/models/__tests__/get-blocks.result.unit.test.ts deleted file mode 100644 index 1ac74c8..0000000 --- a/src/common/blockchain/block-reader/models/__tests__/get-blocks.result.unit.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { Block, Delta, Trace } from '../../../block-content'; -import { deserializeMessage } from '../../block-reader.utils'; -import { ReceivedBlock } from '../received-block'; - -jest.mock('eosjs/dist/eosjs-serialize'); -jest.mock( - '../../block-reader.utils', - jest.fn(() => ({ - deserializeMessage: jest.fn(() => []), - })) -); - -const dto = { - head: { - block_num: 1000, - block_id: '1000', - }, - this_block: { - block_num: 1000, - block_id: '1000', - }, - last_irreversible: { - block_num: 1000, - block_id: '1000', - }, - prev_block: { - block_num: 1000, - block_id: '1000', - }, - block: Uint8Array.from([]), - traces: Uint8Array.from([]), - deltas: Uint8Array.from([]), -}; - -describe('GetBlocksResult Unit tests', () => { - it('"create" should create GetBlocksResult entity based on given DTO', async () => { - const entity = ReceivedBlock.create(dto, new Map()); - expect(entity).toBeInstanceOf(ReceivedBlock); - }); - - it('"create" should call deserializeMessage when result contains block or deltas or traces', async () => { - dto.block = Uint8Array.from([1, 2, 3, 4]); - dto.traces = Uint8Array.from([1, 2, 3, 4]); - dto.deltas = Uint8Array.from([1, 2, 3, 4]); - Block.create = jest.fn().mockReturnValue({}); - Trace.create = jest.fn().mockImplementation(); - Delta.create = jest.fn().mockImplementation(); - ReceivedBlock.create(dto, new Map()); - expect(deserializeMessage).toBeCalledTimes(3); - }); -}); diff --git a/src/common/blockchain/block-reader/models/block-reader.message.ts b/src/common/blockchain/block-reader/models/block-reader.message.ts deleted file mode 100644 index bfcf2f1..0000000 --- a/src/common/blockchain/block-reader/models/block-reader.message.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { Serialize } from 'eosjs'; -import { GetBlocksResultDto } from '../block-reader.dtos'; -import { deserializeMessage } from '../block-reader.utils'; -import { ReceivedBlock } from './received-block'; - -export class BlockReaderMessage { - public static readonly version = 'v0'; - - public static create(dto: Uint8Array, types: Map) { - const result = deserializeMessage('result', dto, types); - let content: unknown; - let type: string; - - if (result) { - const [resultType, contentDto]: [string, unknown] = result; - type = resultType; - content = contentDto; - - if (resultType === `get_blocks_result_${this.version}`) { - return new BlockReaderMessage( - type, - ReceivedBlock.create(content, types) - ); - } - } - - return null; - } - - private constructor( - public readonly type: string, - public readonly content: MessageContentType - ) {} -} diff --git a/src/common/blockchain/block-reader/models/get-blocks-ack.request.ts b/src/common/blockchain/block-reader/models/get-blocks-ack.request.ts deleted file mode 100644 index 13e92d0..0000000 --- a/src/common/blockchain/block-reader/models/get-blocks-ack.request.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Serialize } from 'eosjs'; -import { serializeMessage } from '../block-reader.utils'; - -export class GetBlocksAckRequest { - public readonly version = 'v0'; - - constructor( - public readonly messagesCount: number, - public readonly types: Map - ) {} - - public toUint8Array() { - return serializeMessage( - 'request', - [`get_blocks_ack_request_${this.version}`, { num_messages: this.messagesCount }], - this.types - ); - } -} diff --git a/src/common/blockchain/block-reader/models/index.ts b/src/common/blockchain/block-reader/models/index.ts deleted file mode 100644 index 6ed2875..0000000 --- a/src/common/blockchain/block-reader/models/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './block-reader.message'; -export * from './get-blocks-ack.request'; -export * from './get-blocks.request'; -export * from './received-block'; diff --git a/src/common/blockchain/block-reader/models/received-block.ts b/src/common/blockchain/block-reader/models/received-block.ts deleted file mode 100644 index 0904af3..0000000 --- a/src/common/blockchain/block-reader/models/received-block.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { parseToBigInt } from '@alien-worlds/api-core'; -import { Serialize } from 'eosjs'; -import { Block, BlockDto } from '../../block-content/block'; -import { Delta, DeltaDto } from '../../block-content/delta'; -import { Trace, TraceDto } from '../../block-content/trace'; -import { BlockNumberWithIdDto, GetBlocksResultDto } from '../block-reader.dtos'; -import { deserializeMessage } from '../block-reader.utils'; - -export class BlockNumberWithId { - public static create(dto: BlockNumberWithIdDto) { - const { block_id, block_num } = dto; - return new BlockNumberWithId(parseToBigInt(block_num), block_id); - } - - private constructor( - public readonly blockNumber: bigint, - public readonly blockId: string - ) {} -} - -export class ReceivedBlock { - public static create( - content: GetBlocksResultDto, - types: Map - ): ReceivedBlock { - const { head, last_irreversible, prev_block, this_block } = content; - let block: Block; - let traces: Trace[] = []; - let deltas: Delta[] = []; - - if (content.block && content.block.length > 0) { - const deserializedBlock = deserializeMessage( - 'signed_block', - content.block, - types - ); - block = Block.create(deserializedBlock); - } - - if (content.traces && content.traces.length > 0) { - const tracesByType = deserializeMessage<[[string, TraceDto]]>( - 'transaction_trace[]', - content.traces, - types - ); - traces = tracesByType.map(([shipMessageName, traceDto]) => - Trace.create(shipMessageName, traceDto) - ); - } - - if (content.deltas && content.deltas.length > 0) { - const deltasByType = deserializeMessage<[[string, DeltaDto]]>( - 'table_delta[]', - content.deltas, - types - ); - deltas = deltasByType.map(([shipMessageName, deltaDto]) => - Delta.create(shipMessageName, deltaDto) - ); - } - - return new ReceivedBlock( - head ? BlockNumberWithId.create(head) : null, - this_block ? BlockNumberWithId.create(this_block) : null, - prev_block ? BlockNumberWithId.create(prev_block) : null, - last_irreversible ? BlockNumberWithId.create(last_irreversible) : null, - block, - traces, - deltas - ); - } - - private constructor( - public readonly head: BlockNumberWithId, - public readonly thisBlock: BlockNumberWithId, - public readonly prevBlock: BlockNumberWithId, - public readonly lastIrreversible: BlockNumberWithId, - public readonly block: Block, - public readonly traces: Trace[], - public readonly deltas: Delta[] - ) {} -} diff --git a/src/common/blockchain/blockchain.ts b/src/common/blockchain/blockchain.ts new file mode 100644 index 0000000..dd8f661 --- /dev/null +++ b/src/common/blockchain/blockchain.ts @@ -0,0 +1,45 @@ +import fetch from 'node-fetch'; +import { parseToBigInt } from '@alien-worlds/api-core'; +import { Api, JsonRpc } from 'eosjs'; +import { GetInfoResult } from 'eosjs/dist/eosjs-rpc-interfaces'; +import { BlockchainConfig } from './blockchain.types'; + +export class Blockchain { + public static create(config: BlockchainConfig): Blockchain { + const { endpoint, chainId } = config; + const api = new Api({ + rpc: new JsonRpc(endpoint, { fetch }), + chainId, + signatureProvider: null, + textDecoder: new TextDecoder(), + textEncoder: new TextEncoder(), + }); + + return new Blockchain(endpoint, chainId, api); + } + + private constructor( + protected endpoint: string, + protected chainId: string, + protected api: Api + ) {} + + public getInfo = async (): Promise => { + return this.api.rpc.get_info(); + }; + + public async getHeadBlockNumber(): Promise { + const info = await this.api.rpc.get_info(); + const value = parseToBigInt(info.head_block_num); + return value; + } + + public async getLastIrreversibleBlockNumber(): Promise { + const info = await this.api.rpc.get_info(); + const value = parseToBigInt(info.last_irreversible_block_num); + return value; + } +} + +//log(`Head block number: ${value.toString()}`); +//log(`Last irreversible block number: ${value.toString()}`); \ No newline at end of file diff --git a/src/common/blockchain/blockchain.types.ts b/src/common/blockchain/blockchain.types.ts new file mode 100644 index 0000000..d3479cb --- /dev/null +++ b/src/common/blockchain/blockchain.types.ts @@ -0,0 +1,4 @@ +export type BlockchainConfig = { + endpoint: string; + chainId: string; +}; diff --git a/src/common/blockchain/blockchain.utils.ts b/src/common/blockchain/blockchain.utils.ts deleted file mode 100644 index 9790871..0000000 --- a/src/common/blockchain/blockchain.utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import fetch from 'node-fetch'; -import { log, parseToBigInt } from '@alien-worlds/api-core'; -import { Api, JsonRpc } from 'eosjs'; -import { GetInfoResult } from 'eosjs/dist/eosjs-rpc-interfaces'; - -export const fetchBlockchainInfo = async ( - endpoint: string, - chainId: string -): Promise => { - const api = new Api({ - rpc: new JsonRpc(endpoint, { fetch }), - chainId, - signatureProvider: null, - textDecoder: new TextDecoder(), - textEncoder: new TextEncoder(), - }); - - return api.rpc.get_info(); -}; - -export const getLastIrreversibleBlockNumber = async ( - endpoint: string, - chainId: string -): Promise => { - const info = await fetchBlockchainInfo(endpoint, chainId); - const value = parseToBigInt(info.last_irreversible_block_num); - log(`Last irreversible block number: ${value.toString()}`); - return value; -}; - -export const getHeadBlockNumber = async ( - endpoint: string, - chainId: string -): Promise => { - const info = await fetchBlockchainInfo(endpoint, chainId); - const value = parseToBigInt(info.head_block_num); - log(`Head block number: ${value.toString()}`); - return value; -}; diff --git a/src/common/blockchain/contract-reader/contract-reader.ts b/src/common/blockchain/contract-reader/contract-reader.ts index d13619c..4ccdc4c 100644 --- a/src/common/blockchain/contract-reader/contract-reader.ts +++ b/src/common/blockchain/contract-reader/contract-reader.ts @@ -1,11 +1,32 @@ import fetch from 'node-fetch'; -import { log } from '@alien-worlds/api-core'; +import { MongoConfig, MongoSource, log } from '@alien-worlds/api-core'; import { ContractReaderConfig } from './contract-reader.config'; import { FetchContractResponse } from './contract-reader.dtos'; import { FeaturedContract } from './featured-contract'; import { FeaturedContractSource } from './featured-contract.source'; export abstract class ContractReader { + public static async create( + config: ContractReaderConfig, + mongo: MongoSource | MongoConfig + ): Promise { + let mongoSource: MongoSource; + + log(` * Contract Reader ... [starting]`); + + if (mongo instanceof MongoSource) { + mongoSource = mongo; + } else { + mongoSource = await MongoSource.create(mongo); + } + const source = new FeaturedContractSource(mongoSource); + const contractReader = new ContractReaderService(source, config); + + log(` * Contract Reader ... [ready]`); + + return contractReader; + } + public abstract getInitialBlockNumber(contract: string): Promise; public abstract readContracts(contracts: string[]): Promise; } diff --git a/src/common/blockchain/contract-reader/contract-reader.utils.ts b/src/common/blockchain/contract-reader/contract-reader.utils.ts deleted file mode 100644 index 93166e3..0000000 --- a/src/common/blockchain/contract-reader/contract-reader.utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { log, MongoConfig, MongoSource } from '@alien-worlds/api-core'; -import { ContractReader, ContractReaderService } from './contract-reader'; -import { ContractReaderConfig } from './contract-reader.config'; -import { FeaturedContractSource } from './featured-contract.source'; - -export const setupContractReader = async ( - config: ContractReaderConfig, - mongo: MongoSource | MongoConfig -): Promise => { - let mongoSource: MongoSource; - - log(` * Contract Reader ... [starting]`); - - if (mongo instanceof MongoSource) { - mongoSource = mongo; - } else { - mongoSource = await MongoSource.create(mongo); - } - const source = new FeaturedContractSource(mongoSource); - const contractReader = new ContractReaderService(source, config); - - log(` * Contract Reader ... [ready]`); - - return contractReader; -}; diff --git a/src/common/blockchain/contract-reader/index.ts b/src/common/blockchain/contract-reader/index.ts index 2746bcb..fd79e8c 100644 --- a/src/common/blockchain/contract-reader/index.ts +++ b/src/common/blockchain/contract-reader/index.ts @@ -2,5 +2,4 @@ export * from './contract-reader'; export * from './contract-reader.config'; export * from './contract-reader.dtos'; export * from './featured-contract.source'; -export * from './contract-reader.utils' export * from './featured-contract'; diff --git a/src/common/blockchain/block-content/action-trace/__tests__/action-trace.unit.test.ts b/src/common/blockchain/contract/action-trace/__tests__/action-trace.unit.test.ts similarity index 94% rename from src/common/blockchain/block-content/action-trace/__tests__/action-trace.unit.test.ts rename to src/common/blockchain/contract/action-trace/__tests__/action-trace.unit.test.ts index 2e5c73e..4c82cef 100644 --- a/src/common/blockchain/block-content/action-trace/__tests__/action-trace.unit.test.ts +++ b/src/common/blockchain/contract/action-trace/__tests__/action-trace.unit.test.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Act, ActionTrace, Receipt } from '../action-trace'; -import { ActDto, ActionTraceDto } from '../action-trace.dtos'; +import { ActJson, ActionTraceDto } from '../action-trace.dtos'; -const actDto: ActDto = { +const actDto: ActJson = { account: 'foo.account', name: 'foo.name', authorization: { diff --git a/src/common/blockchain/block-content/action-trace/action-trace.dtos.ts b/src/common/blockchain/contract/action-trace/action-trace.dtos.ts similarity index 84% rename from src/common/blockchain/block-content/action-trace/action-trace.dtos.ts rename to src/common/blockchain/contract/action-trace/action-trace.dtos.ts index e69a4f9..a080d68 100644 --- a/src/common/blockchain/block-content/action-trace/action-trace.dtos.ts +++ b/src/common/blockchain/contract/action-trace/action-trace.dtos.ts @@ -1,29 +1,29 @@ -export type AuthSequenceDto = { +export type AuthSequenceJson = { account: string; sequence: string; }; -export type ReceiptDto = { +export type ReceiptJson = { receiver: string; act_digest: string; global_sequence: string; recv_sequence: string; - auth_sequence: AuthSequenceDto[]; + auth_sequence: AuthSequenceJson[]; code_sequence: number; abi_sequence: number; }; -export type ReceiptByNameDto = [string, ReceiptDto]; +export type ReceiptByNameDto = [string, ReceiptJson]; -export type ActAuthDto = { +export type ActAuthJson = { actor: string; permission: string; }; -export type ActDto = { +export type ActJson = { account: string; name: string; - authorization: ActAuthDto; + authorization: ActAuthJson; data: Uint8Array; }; @@ -33,7 +33,7 @@ export type ActionTraceDto = { creator_action_ordinal?: number; receipt?: ReceiptByNameDto; receiver?: string; - act?: ActDto; + act?: ActJson; context_free?: boolean; elapsed?: string; console?: string; diff --git a/src/common/blockchain/block-content/action-trace/action-trace.ts b/src/common/blockchain/contract/action-trace/action-trace.ts similarity index 91% rename from src/common/blockchain/block-content/action-trace/action-trace.ts rename to src/common/blockchain/contract/action-trace/action-trace.ts index 07f55d0..d461625 100644 --- a/src/common/blockchain/block-content/action-trace/action-trace.ts +++ b/src/common/blockchain/contract/action-trace/action-trace.ts @@ -1,8 +1,8 @@ import { parseToBigInt } from '@alien-worlds/api-core'; -import { ActAuthDto, ActDto, ActionTraceDto, ReceiptDto } from './action-trace.dtos'; +import { ActAuthJson, ActJson, ActionTraceDto, ReceiptJson } from './action-trace.dtos'; export class ActAuth { - public static create(dto: ActAuthDto): ActAuth { + public static create(dto: ActAuthJson): ActAuth { const { actor, permission } = dto; return new ActAuth(actor, permission); @@ -14,7 +14,7 @@ export class ActAuth { } export class Act { - public static create(dto: ActDto): Act { + public static create(dto: ActJson): Act { const { account, name, data } = dto; //parse DATA @@ -40,7 +40,7 @@ export type AuthSequence = { }; export class Receipt { - public static create(shipMessageName: string, dto: ReceiptDto): Receipt { + public static create(shipMessageName: string, dto: ReceiptJson): Receipt { const { receiver, act_digest, diff --git a/src/common/blockchain/block-content/action-trace/index.ts b/src/common/blockchain/contract/action-trace/index.ts similarity index 100% rename from src/common/blockchain/block-content/action-trace/index.ts rename to src/common/blockchain/contract/action-trace/index.ts diff --git a/src/common/blockchain/block-content/delta/__tests__/delta.unit.test.ts b/src/common/blockchain/contract/delta/__tests__/delta.unit.test.ts similarity index 100% rename from src/common/blockchain/block-content/delta/__tests__/delta.unit.test.ts rename to src/common/blockchain/contract/delta/__tests__/delta.unit.test.ts diff --git a/src/common/blockchain/block-content/delta/delta.dtos.ts b/src/common/blockchain/contract/delta/delta.dtos.ts similarity index 79% rename from src/common/blockchain/block-content/delta/delta.dtos.ts rename to src/common/blockchain/contract/delta/delta.dtos.ts index 151f850..f4a013f 100644 --- a/src/common/blockchain/block-content/delta/delta.dtos.ts +++ b/src/common/blockchain/contract/delta/delta.dtos.ts @@ -3,12 +3,12 @@ export type DeltaRowDto = { data?: Uint8Array; }; -export type DeltaDto = { +export type DeltaJson = { name?: string; rows?: DeltaRowDto[]; }; -export type DeltaByNameDto = [string, DeltaDto]; +export type DeltaByNameDto = [string, DeltaJson]; export type DeltaRowModel = { present?: number; diff --git a/src/common/blockchain/block-content/delta/delta.ts b/src/common/blockchain/contract/delta/delta.ts similarity index 82% rename from src/common/blockchain/block-content/delta/delta.ts rename to src/common/blockchain/contract/delta/delta.ts index 82989e6..cd0981b 100644 --- a/src/common/blockchain/block-content/delta/delta.ts +++ b/src/common/blockchain/contract/delta/delta.ts @@ -1,4 +1,4 @@ -import { DeltaDto, DeltaRowDto } from './delta.dtos'; +import { DeltaJson, DeltaRowDto } from './delta.dtos'; export class DeltaRow { public static create(dto: DeltaRowDto): DeltaRow { @@ -13,7 +13,7 @@ export class DeltaRow { } export class Delta { - public static create(shipMessageName: string, dto: DeltaDto): Delta { + public static create(shipMessageName: string, dto: DeltaJson): Delta { const { name, rows } = dto; return new Delta( diff --git a/src/common/blockchain/block-content/delta/index.ts b/src/common/blockchain/contract/delta/index.ts similarity index 100% rename from src/common/blockchain/block-content/delta/index.ts rename to src/common/blockchain/contract/delta/index.ts diff --git a/src/common/blockchain/block-content/index.ts b/src/common/blockchain/contract/index.ts similarity index 52% rename from src/common/blockchain/block-content/index.ts rename to src/common/blockchain/contract/index.ts index d4e84bf..4c0314e 100644 --- a/src/common/blockchain/block-content/index.ts +++ b/src/common/blockchain/contract/index.ts @@ -1,6 +1,5 @@ -export * from './abi'; export * from './action-trace/action-trace'; -export * from './block/block'; +export * from './signed-block'; export * from './delta/delta'; export * from './trace/trace'; -export * from './transaction/transaction'; \ No newline at end of file +export * from './transaction/transaction'; diff --git a/src/common/blockchain/block-content/block/__tests__/block.unit.test.ts b/src/common/blockchain/contract/signed-block/__tests__/block.unit.test.ts similarity index 81% rename from src/common/blockchain/block-content/block/__tests__/block.unit.test.ts rename to src/common/blockchain/contract/signed-block/__tests__/block.unit.test.ts index f581fe8..2afd95a 100644 --- a/src/common/blockchain/block-content/block/__tests__/block.unit.test.ts +++ b/src/common/blockchain/contract/signed-block/__tests__/block.unit.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Block } from '../block'; +import { SignedBlock } from '../signed-block'; const dto = { timestamp: '2022-06-30T12:28:32.900Z', producer: 'some_producer', @@ -34,14 +34,14 @@ describe('Block Unit tests', () => { }); it('"create" should create Block entity based on given DTO', async () => { - const entity = Block.create(dto); - expect(entity).toBeInstanceOf(Block); + const entity = SignedBlock.create(dto); + expect(entity).toBeInstanceOf(SignedBlock); }); it('"create" should use system current timestamp if DTO does not have one', async () => { dto.timestamp = ''; - const entity = Block.create(dto); + const entity = SignedBlock.create(dto); expect(entity.timestamp.toISOString()).toEqual('2022-05-04T22:00:00.000Z'); - expect(entity).toBeInstanceOf(Block); + expect(entity).toBeInstanceOf(SignedBlock); }); }); diff --git a/src/common/blockchain/contract/signed-block/index.ts b/src/common/blockchain/contract/signed-block/index.ts new file mode 100644 index 0000000..0a24efc --- /dev/null +++ b/src/common/blockchain/contract/signed-block/index.ts @@ -0,0 +1,2 @@ +export * from './signed-block'; +export * from './signed-block.dtos'; diff --git a/src/common/blockchain/block-content/block/block.dtos.ts b/src/common/blockchain/contract/signed-block/signed-block.dtos.ts similarity index 91% rename from src/common/blockchain/block-content/block/block.dtos.ts rename to src/common/blockchain/contract/signed-block/signed-block.dtos.ts index 02a6d43..1d736f3 100644 --- a/src/common/blockchain/block-content/block/block.dtos.ts +++ b/src/common/blockchain/contract/signed-block/signed-block.dtos.ts @@ -1,6 +1,6 @@ import { TransactionDto } from '../transaction/transaction.dtos'; -export type BlockDto = { +export type SignedBlockJson = { timestamp: string; producer: string; confirmed: number; diff --git a/src/common/blockchain/block-content/block/block.ts b/src/common/blockchain/contract/signed-block/signed-block.ts similarity index 88% rename from src/common/blockchain/block-content/block/block.ts rename to src/common/blockchain/contract/signed-block/signed-block.ts index 163d13e..86c2074 100644 --- a/src/common/blockchain/block-content/block/block.ts +++ b/src/common/blockchain/contract/signed-block/signed-block.ts @@ -2,10 +2,10 @@ import { parseDateToMs } from '@alien-worlds/api-core'; import { Transaction } from '../transaction/transaction'; -import { BlockDto } from './block.dtos'; +import { SignedBlockJson } from './signed-block.dtos'; -export class Block { - public static create(dto: BlockDto): Block { +export class SignedBlock { + public static create(dto: SignedBlockJson): SignedBlock { const { producer, confirmed, @@ -21,7 +21,7 @@ export class Block { const timestamp = dto.timestamp ? new Date(parseDateToMs(dto.timestamp)) : new Date(); - return new Block( + return new SignedBlock( timestamp, producer, confirmed, diff --git a/src/common/blockchain/block-content/trace/__tests__/trace.unit.test.ts b/src/common/blockchain/contract/trace/__tests__/trace.unit.test.ts similarity index 100% rename from src/common/blockchain/block-content/trace/__tests__/trace.unit.test.ts rename to src/common/blockchain/contract/trace/__tests__/trace.unit.test.ts diff --git a/src/common/blockchain/block-content/trace/index.ts b/src/common/blockchain/contract/trace/index.ts similarity index 100% rename from src/common/blockchain/block-content/trace/index.ts rename to src/common/blockchain/contract/trace/index.ts diff --git a/src/common/blockchain/block-content/trace/trace.dtos.ts b/src/common/blockchain/contract/trace/trace.dtos.ts similarity index 83% rename from src/common/blockchain/block-content/trace/trace.dtos.ts rename to src/common/blockchain/contract/trace/trace.dtos.ts index a387282..b257134 100644 --- a/src/common/blockchain/block-content/trace/trace.dtos.ts +++ b/src/common/blockchain/contract/trace/trace.dtos.ts @@ -1,4 +1,4 @@ -import { ActionTraceByNameDto } from "../action-trace"; +import { ActionTraceByNameDto } from '../action-trace'; export type PartialDto = { expiration: string; @@ -14,7 +14,7 @@ export type PartialDto = { export type PartialByTypeDto = [string, PartialDto]; -export type TraceDto = { +export type TraceJson = { id: string; status: number; cpu_usage_us: number; @@ -30,4 +30,4 @@ export type TraceDto = { partial: PartialByTypeDto; }; -export type TraceByNameDto = [string, TraceDto]; +export type TraceByNameDto = [string, TraceJson]; diff --git a/src/common/blockchain/block-content/trace/trace.ts b/src/common/blockchain/contract/trace/trace.ts similarity index 95% rename from src/common/blockchain/block-content/trace/trace.ts rename to src/common/blockchain/contract/trace/trace.ts index 1a4f849..e0d96ff 100644 --- a/src/common/blockchain/block-content/trace/trace.ts +++ b/src/common/blockchain/contract/trace/trace.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-empty-function */ import { ActionTrace } from '../action-trace/action-trace'; -import { PartialDto, TraceDto } from './trace.dtos'; +import { PartialDto, TraceJson } from './trace.dtos'; export class Partial { public static create(type: string, dto: PartialDto): Partial { @@ -44,7 +44,7 @@ export class Partial { } export class Trace { - public static create(shipMessageName: string, traceDto: TraceDto): Trace { + public static create(shipMessageName: string, traceDto: TraceJson): Trace { const { id, status, diff --git a/src/common/blockchain/block-content/transaction/__tests__/transaction.unit.test.ts b/src/common/blockchain/contract/transaction/__tests__/transaction.unit.test.ts similarity index 100% rename from src/common/blockchain/block-content/transaction/__tests__/transaction.unit.test.ts rename to src/common/blockchain/contract/transaction/__tests__/transaction.unit.test.ts diff --git a/src/common/blockchain/block-content/transaction/index.ts b/src/common/blockchain/contract/transaction/index.ts similarity index 100% rename from src/common/blockchain/block-content/transaction/index.ts rename to src/common/blockchain/contract/transaction/index.ts diff --git a/src/common/blockchain/block-content/transaction/transaction.dtos.ts b/src/common/blockchain/contract/transaction/transaction.dtos.ts similarity index 100% rename from src/common/blockchain/block-content/transaction/transaction.dtos.ts rename to src/common/blockchain/contract/transaction/transaction.dtos.ts diff --git a/src/common/blockchain/block-content/transaction/transaction.ts b/src/common/blockchain/contract/transaction/transaction.ts similarity index 100% rename from src/common/blockchain/block-content/transaction/transaction.ts rename to src/common/blockchain/contract/transaction/transaction.ts diff --git a/src/common/blockchain/index.ts b/src/common/blockchain/index.ts index cee0ac3..93d5885 100644 --- a/src/common/blockchain/index.ts +++ b/src/common/blockchain/index.ts @@ -1,3 +1,6 @@ -export * from './blockchain.utils'; +export * from './abi'; +export * from './blockchain'; +export * from './blockchain.types'; export * from './block-reader'; +export * from './contract'; export * from './contract-reader'; diff --git a/src/common/common.types.ts b/src/common/common.types.ts deleted file mode 100644 index e8553f5..0000000 --- a/src/common/common.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type BlockRangeTaskData = { - startBlock: bigint; - endBlock: bigint; - mode: string; - scanKey: string; -}; diff --git a/src/common/common.utils.ts b/src/common/common.utils.ts index 85fc2e8..493cb86 100644 --- a/src/common/common.utils.ts +++ b/src/common/common.utils.ts @@ -8,3 +8,4 @@ export const wait = async (ms: number) => new Promise(resolve => setTimeout(reso export const isSetAbiAction = (contract: string, action: string) => contract === 'eosio' && action === 'setabi'; + diff --git a/src/common/index.ts b/src/common/index.ts new file mode 100644 index 0000000..69fd9fd --- /dev/null +++ b/src/common/index.ts @@ -0,0 +1,10 @@ +export * from './abis'; +export * from '../reader/block-range-scanner'; +export * from './block-state'; +export * from './blockchain'; +export * from './common.enums'; +export * from './common.errors'; +export * from './common.utils'; +export * from './featured'; +export * from '../processor/processor-task-queue'; +export * from './workers'; diff --git a/src/common/processor-task-queue/processor-task-queue.utils.ts b/src/common/processor-task-queue/processor-task-queue.utils.ts deleted file mode 100644 index 20c694d..0000000 --- a/src/common/processor-task-queue/processor-task-queue.utils.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { log, MongoConfig, MongoSource } from '@alien-worlds/api-core'; -import { ProcessorTaskQueue } from './processor-task-queue'; -import { ProcessorTaskQueueConfig } from './processor-task-queue.config'; - -export const setupProcessorTaskQueue = async ( - mongo: MongoSource | MongoConfig, - onlyAdd: boolean, - queueConfig?: ProcessorTaskQueueConfig -) => { - log(` * Processor Queue ... [starting]`); - - let state: ProcessorTaskQueue; - - if (mongo instanceof MongoSource) { - if (!mongo.client) { - throw new Error( - 'ProcessorTaskQueue requires MongoSource to provide a mongo client. Create Mongo Source using "MongoSource.create()"' - ); - } - - state = new ProcessorTaskQueue(mongo, queueConfig, onlyAdd); - } else { - const mongoSource = await MongoSource.create(mongo); - state = new ProcessorTaskQueue(mongoSource, queueConfig, onlyAdd); - } - - log(` * Processor Queue ... [ready]`); - return state; -}; diff --git a/src/common/ship/index.ts b/src/common/ship/index.ts new file mode 100644 index 0000000..2f49e19 --- /dev/null +++ b/src/common/ship/index.ts @@ -0,0 +1,2 @@ +export * from './ship-abis'; +export * from './ship-abi.source'; diff --git a/src/common/ship/ship-abi.source.ts b/src/common/ship/ship-abi.source.ts new file mode 100644 index 0000000..2d2cbc0 --- /dev/null +++ b/src/common/ship/ship-abi.source.ts @@ -0,0 +1,55 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import { + CollectionMongoSource, + Failure, + MongoDB, + MongoSource, + Result, +} from '@alien-worlds/api-core'; +import { AbiNotFoundError } from '../blockchain/block-reader/block-reader.errors'; +import { Abi } from '../blockchain/abi'; + +export type ShipAbiDocument = { + _id?: MongoDB.ObjectId; + last_modified_timestamp: Date; + version: string; + abi: string; +}; + +export class ShipAbiSource { + private collection: CollectionMongoSource; + + constructor(mongoSource: MongoSource) { + this.collection = new CollectionMongoSource(mongoSource, 'history_tools.ship_abis'); + } + + public async updateAbi(abi: Abi): Promise> { + try { + await this.collection.update({ + version: abi.version, + last_modified_timestamp: new Date(), + abi: abi.toHex(), + }); + + return Result.withoutContent(); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } + } + + public async getAbi(version: string): Promise> { + try { + const document = await this.collection.findOne({ filter: { version } }); + + if (document) { + return Result.withContent(Abi.fromHex(document.abi)); + } + return Result.withFailure(Failure.fromError(new AbiNotFoundError())); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } + } +} diff --git a/src/common/ship/ship-abis.ts b/src/common/ship/ship-abis.ts new file mode 100644 index 0000000..a9f62f3 --- /dev/null +++ b/src/common/ship/ship-abis.ts @@ -0,0 +1,37 @@ +import { MongoConfig, MongoSource, Result, isMongoConfig } from '@alien-worlds/api-core'; +import { ShipAbiSource } from './ship-abi.source'; +import { Abi } from '../blockchain/abi'; + +export class ShipAbis { + public static async create(mongo: MongoConfig | MongoSource) { + let mongoSource; + + if (isMongoConfig(mongo)) { + mongoSource = await MongoSource.create(mongo); + } else { + mongoSource = mongo; + } + + return new ShipAbis(new ShipAbiSource(mongoSource)); + } + + private cache: Map = new Map(); + + private constructor(private mongo: ShipAbiSource) {} + + public async getAbi(version: string): Promise> { + if (this.cache.has(version)) { + return Result.withContent(this.cache.get(version)); + } + + const result = await this.mongo.getAbi(version); + + if (result.isFailure) { + return result; + } + + this.cache.set(version, result.content); + + return result; + } +} diff --git a/src/common/workers/index.ts b/src/common/workers/index.ts index fe945d0..fee6f93 100644 --- a/src/common/workers/index.ts +++ b/src/common/workers/index.ts @@ -1,6 +1,5 @@ export * from './worker-message'; -export * from './worker-pool/worker-pool'; -export * from './worker-pool/worker-pool.utils'; +export * from './worker-pool'; export * from './worker'; export * from './worker.enums'; export * from './worker.errors'; diff --git a/src/common/workers/worker-loader/worker-loader-script.ts b/src/common/workers/worker-loader/worker-loader-script.ts index dda70bf..910e6ef 100644 --- a/src/common/workers/worker-loader/worker-loader-script.ts +++ b/src/common/workers/worker-loader/worker-loader-script.ts @@ -24,7 +24,7 @@ export const messageHandler = async (message: WorkerMessage) => { // try { const { data } = >message; - worker = await workerLoader.load(data || pointer, options?.containerPath); + worker = await workerLoader.load(data || pointer); parentPort.postMessage(WorkerMessage.loadComplete(message.workerId)); } catch (error) { parentPort.postMessage(WorkerMessage.loadFailure(message.workerId, error)); @@ -39,7 +39,7 @@ export const messageHandler = async (message: WorkerMessage) => { } } else if (message.name === WorkerMessageName.RunTask) { // - worker.run(message.data, sharedData); + worker.run(message.data); } }; diff --git a/src/common/workers/worker-loader/worker-loader.errors.ts b/src/common/workers/worker-loader/worker-loader.errors.ts new file mode 100644 index 0000000..253855c --- /dev/null +++ b/src/common/workers/worker-loader/worker-loader.errors.ts @@ -0,0 +1,7 @@ +export class UndefinedPointerError extends Error { + constructor() { + super( + `Undefined pointer. The worker loader does not know which Worker class to initialize. If you use only one class, override your worker loader's "load" method so that it returns instance of your worker instead of calling super.load()` + ); + } +} diff --git a/src/common/workers/worker-loader/worker-loader.ts b/src/common/workers/worker-loader/worker-loader.ts index 48c8c48..35e0133 100644 --- a/src/common/workers/worker-loader/worker-loader.ts +++ b/src/common/workers/worker-loader/worker-loader.ts @@ -1,23 +1,53 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { existsSync } from 'fs'; import { Worker } from '../worker'; -import { getWorkerClass } from './worker-loader.utils'; +import { buildPath } from './worker-loader.utils'; +import { WorkerClass } from '../worker.types'; +import { WorkerConstructorArgs } from './worker-loader.types'; +import { UndefinedPointerError } from './worker-loader.errors'; -export abstract class WorkerLoader { - public abstract setup(...args: unknown[]): Promise; - public abstract load(pointer: string, containerPath: string): Promise; +export abstract class WorkerLoader { + public abstract bindings: Map; + + public abstract setup(sharedData: SharedDataType, ...args: unknown[]): Promise; + public abstract load( + pointer: string, + workerConstructorArgs?: WorkerConstructorArgs + ): Promise; } -export class DefaultWorkerLoader implements WorkerLoader { - public async setup(...args: unknown[]): Promise { - // +export class DefaultWorkerLoader + implements WorkerLoader +{ + public bindings: Map = new Map(); + protected sharedData: SharedDataType; + + public async setup(sharedData: SharedDataType, ...args: unknown[]): Promise { + this.sharedData = sharedData; } public async load( pointer: string, - containerPath: string, - ...workerConstructorArgs: unknown[] + workerConstructorArgs?: WorkerConstructorArgs ): Promise { - const WorkerClass = getWorkerClass(pointer, containerPath); - const worker = new WorkerClass(...workerConstructorArgs) as Worker; + let WorkerClass; + + if (!pointer) { + throw new UndefinedPointerError(); + } + + const filePath = buildPath(pointer); + if (existsSync(filePath)) { + WorkerClass = require(filePath).default; + } else if (this.bindings.has(pointer)) { + WorkerClass = this.bindings.get(pointer); + } else { + throw new Error( + `A valid path to a worker was not specified or a worker was not assigned to the given name ${pointer}` + ); + } + + const worker = new WorkerClass(workerConstructorArgs) as Worker; return worker; } } diff --git a/src/common/workers/worker-loader/worker-loader.types.ts b/src/common/workers/worker-loader/worker-loader.types.ts index 62a3e92..dbdf3c1 100644 --- a/src/common/workers/worker-loader/worker-loader.types.ts +++ b/src/common/workers/worker-loader/worker-loader.types.ts @@ -1 +1,2 @@ export type WorkerLoaderClass = new (...args: never[]) => void; +export type WorkerConstructorArgs = { [key: string]: unknown }; diff --git a/src/common/workers/worker-loader/worker-loader.utils.ts b/src/common/workers/worker-loader/worker-loader.utils.ts index 85db9e8..5fb79f2 100644 --- a/src/common/workers/worker-loader/worker-loader.utils.ts +++ b/src/common/workers/worker-loader/worker-loader.utils.ts @@ -2,9 +2,7 @@ import { existsSync } from 'fs'; import path from 'path'; -import { WorkerContainer } from '../worker-container'; import { InvalidPathError } from '../worker.errors'; -import { WorkerClass } from '../worker.types'; import { DefaultWorkerLoader, WorkerLoader } from './worker-loader'; export const buildPath = (filePath: string): string => { @@ -20,34 +18,6 @@ export const buildPath = (filePath: string): string => { } }; -export const getWorkerClass = (pointer: string, containerPath: string): WorkerClass => { - let WorkerClass; - let filePath: string; - if (pointer && !containerPath) { - filePath = buildPath(pointer); - if (existsSync(filePath) === false) { - throw new InvalidPathError(filePath); - } - WorkerClass = require(filePath).default; - // - } else if (pointer && containerPath) { - filePath = buildPath(containerPath); - if (existsSync(filePath) === false) { - throw new InvalidPathError(filePath); - } - const container: WorkerContainer = require(filePath).default; - - WorkerClass = container.get(pointer); - } else { - throw new Error(`Neither "pointer" nor "containerPath" are given`); - } - - if (!WorkerClass) { - throw new Error(`Default class not found. Use "export default class ..."`); - } - return WorkerClass; -}; - export const getWorkerLoader = (path: string): WorkerLoader => { if (path) { const loaderPath = buildPath(path); diff --git a/src/common/workers/worker-message.ts b/src/common/workers/worker-message.ts index 1ea92bd..d00e582 100644 --- a/src/common/workers/worker-message.ts +++ b/src/common/workers/worker-message.ts @@ -1,9 +1,16 @@ +export type ErrorJson = { + name?: string; + message?: string; + stack?: string; + [key: string]: unknown; +}; + export type WorkerMessageContent = { workerId: number; type: string; name: string; data?: DataType; - error?: Error; + error?: ErrorJson; }; export type WorkerMessageHandler = (message: WorkerMessage) => void; @@ -16,7 +23,7 @@ export class WorkerMessage { data, error, }: WorkerMessageContent) { - let errorJson: Error; + let errorJson: ErrorJson; if (error) { const { message, stack, name: errorName, ...rest } = error; errorJson = { @@ -47,7 +54,8 @@ export class WorkerMessage { workerId, WorkerMessageType.System, WorkerMessageName.SetupFailure, - error + error, + error ); } @@ -73,7 +81,8 @@ export class WorkerMessage { workerId, WorkerMessageType.System, WorkerMessageName.LoadFailure, - error + error, + error ); } @@ -98,7 +107,8 @@ export class WorkerMessage { workerId, WorkerMessageType.System, WorkerMessageName.DisposeComplete, - error + error, + error ); } @@ -135,7 +145,16 @@ export class WorkerMessage { WorkerMessageType.Error, WorkerMessageName.TaskRejected, null, - error + error + ); + } + + public static taskProgress(workerId: number, value: DataType) { + return new WorkerMessage( + workerId, + WorkerMessageType.Info, + WorkerMessageName.TaskProgress, + value ); } @@ -144,13 +163,21 @@ export class WorkerMessage { public readonly type: string, public readonly name: string, public readonly data?: DataType, - public readonly error?: Error + public readonly error?: ErrorJson ) {} public isTaskResolved(): boolean { return this.name === WorkerMessageName.TaskResolved; } + public isTaskRejected(): boolean { + return this.name === WorkerMessageName.TaskRejected; + } + + public isTaskProgress(): boolean { + return this.name === WorkerMessageName.TaskProgress; + } + public toJson(): object { const { workerId, type, name, data, error } = this; let errorJson = {}; @@ -196,4 +223,5 @@ export enum WorkerMessageName { DataPassed = 'data_passed', TaskResolved = 'task_resolved', TaskRejected = 'task_rejected', + TaskProgress = 'task_progress', } diff --git a/src/common/workers/worker-pool/worker-pool.ts b/src/common/workers/worker-pool.ts similarity index 59% rename from src/common/workers/worker-pool/worker-pool.ts rename to src/common/workers/worker-pool.ts index a15d505..53cd41b 100644 --- a/src/common/workers/worker-pool/worker-pool.ts +++ b/src/common/workers/worker-pool.ts @@ -1,38 +1,33 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { log } from '@alien-worlds/api-core'; -import { WorkerProxy } from '../worker-proxy'; -import { - MissingWorkerPathError, - WorkerPoolPathsConflictError, - WorkerPathMismatchError, -} from '../worker.errors'; -import { WorkerPoolOptions } from '../worker.types'; -import { getWorkersCount } from '../worker.utils'; - -type Handler = (...args: unknown[]) => Promise | void; - -export class WorkerPool { +import { WorkerProxy } from './worker-proxy'; +import { WorkerPoolOptions } from './worker.types'; +import { getWorkersCount } from './worker.utils'; + +type WorkerReleaseHandler = (id: number, data?: unknown) => Promise | void; + +export class WorkerPool { + public static async create(options: WorkerPoolOptions) { + const pool = new WorkerPool(); + await pool.setup(options); + return pool; + } + public workerMaxCount: number; - private globalWorkerPath: string; - private containerPath: string; private workerLoaderPath: string; private availableWorkers: WorkerProxy[] = []; private activeWorkersByPid = new Map(); private sharedData: unknown; - private workerReleaseHandler: Handler; + private workerReleaseHandler: WorkerReleaseHandler; public async setup(options: WorkerPoolOptions) { const { threadsCount, inviolableThreadsCount, - globalWorkerPath, sharedData, - containerPath, workerLoaderPath, } = options; - this.globalWorkerPath = globalWorkerPath; - this.containerPath = containerPath; this.workerLoaderPath = workerLoaderPath; this.sharedData = sharedData; this.workerMaxCount = @@ -40,10 +35,6 @@ export class WorkerPool { ? getWorkersCount(threadsCount, inviolableThreadsCount) : threadsCount; - if (containerPath && globalWorkerPath) { - throw new WorkerPoolPathsConflictError(); - } - for (let i = 0; i < this.workerMaxCount; i++) { const worker = await this.createWorker(); this.availableWorkers.push(worker); @@ -55,41 +46,29 @@ export class WorkerPool { } private async createWorker(): Promise { - const { sharedData, containerPath, workerLoaderPath } = this; - const proxy = new WorkerProxy(sharedData, { workerLoaderPath, containerPath }); + const { sharedData, workerLoaderPath } = this; + const proxy = new WorkerProxy(sharedData, { workerLoaderPath }); await proxy.setup(); return proxy; } - public async getWorker(pointer?: string): Promise { - const { globalWorkerPath, activeWorkersByPid, workerMaxCount, availableWorkers } = + public async getWorker(pointer?: string): Promise { + const { activeWorkersByPid, workerMaxCount, availableWorkers } = this; - // Without an assigned process path, worker processes cannot be created. - if (!pointer && !globalWorkerPath) { - throw new MissingWorkerPathError(); - } - - // In the options, you can specify a path to a common/global process to all workers - // also you can specify a path to a file with a list of available processes. - // But you cannot specify both of these options at the same time! - if (pointer && globalWorkerPath && pointer !== globalWorkerPath) { - throw new WorkerPathMismatchError(pointer, globalWorkerPath); - } - if (activeWorkersByPid.size < workerMaxCount) { // When workers are to run common or concrete process, // we use instance from the list (if there is any available) const worker = availableWorkers.shift(); activeWorkersByPid.set(worker.id, worker); - await worker.load(pointer || globalWorkerPath); - return worker; + await worker.load(pointer); + return worker as WorkerType & WorkerProxy; } else { return null; } } - public async releaseWorker(id: number): Promise { + public async releaseWorker(id: number, data?: unknown): Promise { const { activeWorkersByPid, availableWorkers, workerMaxCount, workerReleaseHandler } = this; const worker = activeWorkersByPid.get(id); @@ -101,7 +80,7 @@ export class WorkerPool { availableWorkers.push(worker); } if (workerReleaseHandler) { - await workerReleaseHandler(id); + await workerReleaseHandler(id, data); } } else { log(`No worker with the specified ID #${id} was found`); @@ -129,7 +108,7 @@ export class WorkerPool { return this.activeWorkersByPid.size; } - public onWorkerRelease(handler: Handler): void { + public onWorkerRelease(handler: WorkerReleaseHandler): void { this.workerReleaseHandler = handler; } } diff --git a/src/common/workers/worker-pool/worker-pool.utils.ts b/src/common/workers/worker-pool/worker-pool.utils.ts deleted file mode 100644 index 92db437..0000000 --- a/src/common/workers/worker-pool/worker-pool.utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { WorkerPool } from './worker-pool'; -import { WorkerPoolOptions } from '../worker.types'; - -export const createWorkerPool = async (options: WorkerPoolOptions) => { - const pool = new WorkerPool(); - await pool.setup(options); - return pool; -}; diff --git a/src/common/workers/worker-proxy.ts b/src/common/workers/worker-proxy.ts index badc72f..499905c 100644 --- a/src/common/workers/worker-proxy.ts +++ b/src/common/workers/worker-proxy.ts @@ -99,7 +99,7 @@ export class WorkerProxy { }); } - public run(data: DataType): void { + public run(data?: DataType): void { const { worker } = this; worker.postMessage(WorkerMessage.runTask(worker.threadId, data).toJson()); } @@ -112,12 +112,12 @@ export class WorkerProxy { }); } - public onError(handler: (error: Error) => void) { - this.worker.on('error', handler); + public onError(handler: (workerId: number, error: Error) => void) { + this.worker.on('error', error => handler(this.worker.threadId, error)); } - public onExit(handler: (code: number) => void) { - this.worker.on('exit', handler); + public onExit(handler: (workerId: number, code: number) => void) { + this.worker.on('exit', code => handler(this.worker.threadId, code)); } public async remove(): Promise { diff --git a/src/common/workers/worker.errors.ts b/src/common/workers/worker.errors.ts index e4c8ba6..b43dcd6 100644 --- a/src/common/workers/worker.errors.ts +++ b/src/common/workers/worker.errors.ts @@ -21,7 +21,7 @@ export class WorkerNotFoundError extends Error { export class WorkerPoolPathsConflictError extends Error { constructor() { super( - `"globalWorkerPath" and "containerPath" cannot be specified at the same time, both options are mutually exclusive.` + `default worker path and "containerPath" cannot be specified at the same time, both options are mutually exclusive.` ); } } diff --git a/src/common/workers/worker.ts b/src/common/workers/worker.ts index 741441e..81a2948 100644 --- a/src/common/workers/worker.ts +++ b/src/common/workers/worker.ts @@ -6,26 +6,42 @@ import { WorkerMessage } from './worker-message'; export type TaskResolved = 'task_resolved'; export type TaskRejected = 'task_rejected'; -export type TaskStatus = TaskResolved | TaskRejected; +export type TaskProgress = 'task_progress'; +export type TaskStatus = TaskResolved | TaskRejected | TaskProgress; -export abstract class Worker { +export class Worker { public get id(): number { return threadId; } - public abstract run(data: DataType, sharedData: SharedDataType): void; + protected sharedData: SharedDataType; + private isRejected = false; + + public run(...args: unknown[]): void { + throw new Error('Method not implemented'); + } public deserialize(data: unknown): unknown { throw new Error('Method not implemented'); } - public resolve(data?: unknown): TaskResolved { - parentPort.postMessage(WorkerMessage.taskResolved(threadId, data).toJson()); - return 'task_resolved'; + public resolve(data?: DataType): TaskResolved { + if (this.isRejected === false) { + parentPort.postMessage( + WorkerMessage.taskResolved(threadId, data).toJson() + ); + return 'task_resolved'; + } } public reject(error?: Error): TaskRejected { parentPort.postMessage(WorkerMessage.taskRejected(threadId, error).toJson()); + this.isRejected = true; return 'task_rejected'; } + + public progress(data?: DataType): TaskProgress { + parentPort.postMessage(WorkerMessage.taskProgress(threadId, data).toJson()); + return 'task_progress'; + } } diff --git a/src/common/workers/worker.types.ts b/src/common/workers/worker.types.ts index 85a7ec5..adb88a1 100644 --- a/src/common/workers/worker.types.ts +++ b/src/common/workers/worker.types.ts @@ -1,21 +1,21 @@ -export type WorkersConfig = { +export type PathsByNames = { + default?: string; + [key: string]: string; +}; + +export type WorkersConfig = { threadsCount?: number; inviolableThreadsCount?: number; - containerPath?: string; - globalWorkerPath?: string; - sharedData?: unknown; + sharedData?: SharedDataType; [key: string]: unknown; }; -export type WorkerPoolOptions = WorkersConfig & { - workerLoaderPath?: string; -}; - export type WorkerProxyOptions = { - containerPath?: string; workerLoaderPath?: string; }; +export type WorkerPoolOptions = WorkersConfig & WorkerProxyOptions; + export type WorkerData = { pointer: string; sharedData?: unknown; diff --git a/src/config.ts b/src/config.ts deleted file mode 100644 index 39c3aed..0000000 --- a/src/config.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; -import { ApiConfig } from './api'; -import { AbisConfig } from './common/abis'; -import { BlockRangeScanConfig } from './common/block-range-scanner'; -import { BlockReaderConfig } from './common/blockchain/block-reader'; -import { ContractReaderConfig } from './common/blockchain/contract-reader'; -import { FeaturedConfig } from './common/featured'; -import { ProcessorTaskQueueConfig } from './common/processor-task-queue/processor-task-queue.config'; -import { WorkersConfig } from './common/workers'; - -export type HistoryToolsConfig = { - api: ApiConfig; - broadcast: BroadcastConfig; - blockchain: { - endpoint: string; - chainId: string; - [key: string]: unknown; - }; - scanner: BlockRangeScanConfig; - blockReader: BlockReaderConfig; - contractReader: ContractReaderConfig; - mongo: MongoConfig; - featured: FeaturedConfig; - abis: AbisConfig; - processor: { - workers: WorkersConfig; - taskQueue: ProcessorTaskQueueConfig; - [key: string]: unknown; - }; - blockRange: { workers: WorkersConfig, maxBlockNumber?: number }; - startBlock: bigint; - endBlock: bigint; - startFromHead: boolean; - mode: string; - [key: string]: unknown; -}; diff --git a/src/config/config.types.ts b/src/config/config.types.ts new file mode 100644 index 0000000..f05bf20 --- /dev/null +++ b/src/config/config.types.ts @@ -0,0 +1,14 @@ +import { ApiConfig } from '../api'; +import { BootstrapConfig } from '../bootstrap'; +import { ReaderConfig } from '../reader'; +import { FilterConfig } from '../filter'; +import { ProcessorConfig } from '../processor'; + +export type HistoryToolsConfig = { + api: ApiConfig; + bootstrap: BootstrapConfig; + reader: ReaderConfig; + filter: FilterConfig; + processor: ProcessorConfig; + [key: string]: unknown; +}; \ No newline at end of file diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 0000000..cd6f6d7 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,183 @@ +import { ProcessorTaskQueueConfig } from '../processor/processor-task-queue/processor-task-queue.config'; +import { + ConfigVars, + buildBroadcastConfig, + buildMongoConfig, + parseToBigInt, +} from '@alien-worlds/api-core'; +import { ApiConfig } from '../api'; +import { BootstrapConfig, BootstrapCommandOptions } from '../bootstrap'; +import { ReaderConfig, ReaderCommandOptions } from '../reader'; +import { FilterConfig, FilterCommandOptions } from '../filter'; +import { ProcessorConfig, ProcessorCommandOptions } from '../processor'; +import { HistoryToolsConfig } from './config.types'; +import { + AbisConfig, + AbisServiceConfig, + BlockRangeScanConfig, + BlockReaderConfig, + ContractReaderConfig, + FeaturedConfig, + WorkersConfig, +} from '../common'; + +export * from './config.types'; + +export const buildBlockchainConfig = ( + vars: ConfigVars +): { endpoint: string; chainId: string } => ({ + endpoint: vars.getStringEnv('BLOCKCHAIN_ENDPOINT'), + chainId: vars.getStringEnv('BLOCKCHAIN_CHAIN_ID'), +}); + +export const buildContractReaderConfig = (vars: ConfigVars): ContractReaderConfig => ({ + url: vars.getStringEnv('HYPERION_URL'), +}); + +export const buildBlockRangeScanConfig = ( + vars: ConfigVars, + scanKey?: string +): BlockRangeScanConfig => ({ + maxChunkSize: vars.getNumberEnv('SCANNER_NODES_MAX_CHUNK_SIZE'), + scanKey: scanKey || vars.getStringEnv('SCANNER_SCAN_KEY'), +}); + +export const buildAbisServiceConfig = (vars: ConfigVars): AbisServiceConfig => ({ + url: vars.getStringEnv('HYPERION_URL'), + limit: vars.getNumberEnv('ABIS_SERVICE_LIMIT'), + filter: vars.getStringEnv('ABIS_SERVICE_FILTER'), +}); + +export const buildAbisConfig = ( + vars: ConfigVars, + featured: FeaturedConfig +): AbisConfig => ({ + service: buildAbisServiceConfig(vars), + mongo: buildMongoConfig(vars), + featured, +}); + +export const buildBlockReaderConfig = (vars: ConfigVars): BlockReaderConfig => ({ + mongo: buildMongoConfig(vars), + endpoints: vars.getArrayEnv('BLOCK_READER_ENDPOINTS'), + shouldFetchDeltas: vars.getBooleanEnv('BLOCK_READER_FETCH_DELTAS'), + shouldFetchTraces: vars.getBooleanEnv('BLOCK_READER_FETCH_TRACES'), +}); + +export const buildReaderWorkersConfig = ( + vars: ConfigVars, + threadsCount?: number +): WorkersConfig => ({ + threadsCount: threadsCount || vars.getNumberEnv('READER_MAX_THREADS'), + inviolableThreadsCount: vars.getNumberEnv('READER_INVIOLABLE_THREADS_COUNT'), +}); + +export const buildProcessorWorkersConfig = ( + vars: ConfigVars, + threadsCount?: number +): WorkersConfig => ({ + threadsCount: threadsCount || vars.getNumberEnv('PROCESSOR_MAX_THREADS'), + inviolableThreadsCount: vars.getNumberEnv('PROCESSOR_INVIOLABLE_THREADS_COUNT'), +}); + +export const buildFilterWorkersConfig = ( + vars: ConfigVars, + options?: FilterCommandOptions +): WorkersConfig => ({ + threadsCount: options?.threads || vars.getNumberEnv('FILTER_MAX_THREADS'), + inviolableThreadsCount: vars.getNumberEnv('FILTER_INVIOLABLE_THREADS_COUNT'), +}); + +export const buildProcessorTaskQueueConfig = ( + vars: ConfigVars +): ProcessorTaskQueueConfig => ({ + interval: vars.getNumberEnv('PROCESSOR_TASK_QUEUE_CHECK_INTERVAL'), +}); + +export const buildApiConfig = (vars: ConfigVars): ApiConfig => ({ + port: vars.getNumberEnv('API_PORT'), + mongo: buildMongoConfig(vars), +}); + +export const buildBootstrapConfig = ( + vars: ConfigVars, + featured: FeaturedConfig, + options?: BootstrapCommandOptions +): BootstrapConfig => ({ + mongo: buildMongoConfig(vars), + broadcast: buildBroadcastConfig(vars), + blockchain: buildBlockchainConfig(vars), + contractReader: buildContractReaderConfig(vars), + scanner: buildBlockRangeScanConfig(vars, options?.scanKey), + startBlock: options?.startBlock + ? parseToBigInt(options?.startBlock) + : vars.getStringEnv('START_BLOCK') + ? parseToBigInt(vars.getStringEnv('START_BLOCK')) + : null, + endBlock: options?.endBlock + ? parseToBigInt(options?.endBlock) + : vars.getStringEnv('END_BLOCK') + ? parseToBigInt(vars.getStringEnv('END_BLOCK')) + : null, + startFromHead: vars.getBooleanEnv('START_FROM_HEAD'), + mode: options?.mode || vars.getStringEnv('MODE'), + featured, + abis: buildAbisServiceConfig(vars), + maxBlockNumber: vars.getNumberEnv('MAX_BLOCK_NUMBER'), +}); + +export const buildReaderConfig = ( + vars: ConfigVars, + options?: ReaderCommandOptions +): ReaderConfig => ({ + mongo: buildMongoConfig(vars), + broadcast: buildBroadcastConfig(vars), + scanner: buildBlockRangeScanConfig(vars, options?.scanKey), + mode: options?.mode || vars.getStringEnv('MODE'), + maxBlockNumber: vars.getNumberEnv('MAX_BLOCK_NUMBER'), + blockQueueMaxBytesSize: vars.getNumberEnv('UNPROCESSED_BLOCK_QUEUE_MAX_BYTES_SIZE'), + blockQueueSizeCheckInterval: vars.getNumberEnv('UNPROCESSED_BLOCK_QUEUE_SIZE_CHECK_INTERVAL'), + blockQueueBatchSize: vars.getNumberEnv('UNPROCESSED_BLOCK_QUEUE_BATCH_SIZE'), + workers: buildReaderWorkersConfig(vars, options?.threads), + blockReader: buildBlockReaderConfig(vars), + startBlock: options?.startBlock ? parseToBigInt(options?.startBlock) : null, + endBlock: options?.endBlock ? parseToBigInt(options?.endBlock) : null, +}); + +export const buildFilterConfig = ( + vars: ConfigVars, + featured: FeaturedConfig, + options?: FilterCommandOptions +): FilterConfig => ({ + mode: options?.mode || vars.getStringEnv('MODE'), + broadcast: buildBroadcastConfig(vars), + workers: buildFilterWorkersConfig(vars, options), + featured, + abis: buildAbisConfig(vars, featured), + contractReader: buildContractReaderConfig(vars), + mongo: buildMongoConfig(vars), + queue: buildProcessorTaskQueueConfig(vars), +}); + +export const buildProcessorConfig = ( + vars: ConfigVars, + featured: FeaturedConfig, + options?: ProcessorCommandOptions +): ProcessorConfig => ({ + broadcast: buildBroadcastConfig(vars), + workers: buildProcessorWorkersConfig(vars, options?.threads), + featured, + mongo: buildMongoConfig(vars), + queue: buildProcessorTaskQueueConfig(vars), +}); + +export const buildHistoryToolsConfig = ( + vars: ConfigVars, + featured: FeaturedConfig +): HistoryToolsConfig => ({ + api: buildApiConfig(vars), + bootstrap: buildBootstrapConfig(vars, featured), + reader: buildReaderConfig(vars), + filter: buildFilterConfig(vars, featured), + processor: buildProcessorConfig(vars, featured), +}); diff --git a/src/filler/__tests__/start-filler.unit.test.ts b/src/filler/__tests__/start-filler.unit.test.ts deleted file mode 100644 index 76a6a99..0000000 --- a/src/filler/__tests__/start-filler.unit.test.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { getLastIrreversibleBlockNumber } from "../../common/blockchain/blockchain.utils"; -import { Mode } from "../../common/common.enums"; -import { UnknownModeError } from "../../common/common.errors"; -import { UndefinedStartBlockError } from "../filler.errors"; -import { prepareDefaultModeInput, prepareReplayModeInput, prepareTestModeInput } from "../filler.utils"; -import { startFiller } from "../start-filler"; - -jest.mock('mongodb') - -jest.mock('../../common/blockchain/blockchain.utils'); -jest.mock('../../block-range/broadcast/block-range.broadcast', jest.fn( - () => ({setupBlockRangeBroadcast: () => broadcastMock}) -)); -jest.mock('../../common/block-range-scanner/block-range-scanner.utils'); -jest.mock('../../common/block-state/block-state.utils'); -jest.mock('../../common/abis/abis.utils', () => ({ - setupAbis: (...args: any[]) => ({fetchAbis: jest.fn()}) -})); - -const config = { - startBlock: 0n, - endBlock: 1n, - mode: Mode.Default, - scanner: { scanKey: 'test' }, - blockchain: { chainId: '', endpoint: '' }, - workers: { - sharedData: { - config: { url: 'mongodb://localhost', dbName: '' } - } - }, - mongo: { url: '', dbName: '' }, - abis: {}, -}; - -const broadcastMock = { - onBlockRangeReadyMessage: jest.fn(), - sendMessage: jest.fn(), -} - -const blockStateMock = { - getCurrentBlockNumber: jest.fn(), -} - -const scannerMock = { - hasUnscannedBlocks: jest.fn(), - createScanNodes: jest.fn(), -} - -describe('StartFiller Unit tests', () => { - it('"prepareDefaultModeInput" should ', async () => { - let input; - input = await prepareDefaultModeInput(blockStateMock as any, config as any); - - expect(input.toJson()).toEqual({ - startBlock: 0n, - endBlock: 1n, - mode: Mode.Default, - scanKey: 'test', - }); - - blockStateMock.getCurrentBlockNumber.mockResolvedValue(100n) - input = await prepareDefaultModeInput(blockStateMock as any, { mode: Mode.Default, - scanner: { scanKey: 'test' }, - blockchain: { chainId: '', endpoint: '' }} as any); - - expect(input.toJson()).toEqual({ - startBlock: 100n, - endBlock: 4294967295n, - mode: Mode.Default, - scanKey: 'test', - }); - }); - - it('"prepareTestModeInput" should ', async () => { - let input; - - input = await prepareTestModeInput(config as any); - - expect(input.toJson()).toEqual({ - startBlock: 0n, - endBlock: 1n, - mode: Mode.Default, - scanKey: 'test', - }); - - input = await prepareTestModeInput({ mode: Mode.Default, - startBlock: 5n, - scanner: { scanKey: 'test' }, - blockchain: { chainId: '', endpoint: '' }} as any); - - expect(input.toJson()).toEqual({ - startBlock: 5n, - endBlock: 6n, - mode: Mode.Default, - scanKey: 'test', - }); - - (getLastIrreversibleBlockNumber as jest.Mock).mockImplementation(() => 100n); - input = await prepareTestModeInput({ - startBlock: 5n, - mode: Mode.Default, - scanner: { scanKey: 'test' }, - blockchain: { chainId: '', endpoint: '' }} as any); - - expect(input.toJson()).toEqual({ - startBlock: 5n, - endBlock: 6n, - mode: Mode.Default, - scanKey: 'test', - }); - - }); - - it('"prepareReplayModeInput" should ', async () => { - let input; - - scannerMock.hasUnscannedBlocks.mockResolvedValue(true); - input = await prepareReplayModeInput(scannerMock as any, config as any); - - expect(input).toEqual({ - startBlock: 0n, - endBlock: 1n, - mode: Mode.Default, - scanKey: 'test', - }); - - try { - scannerMock.hasUnscannedBlocks.mockResolvedValue(false); - scannerMock.createScanNodes.mockResolvedValue({}); - (getLastIrreversibleBlockNumber as jest.Mock).mockImplementation(() => 100n); - input = await prepareReplayModeInput(scannerMock as any, {...config, startBlock: null, endBlock: 200n} as any); - } catch(e) { - expect(e).toBeInstanceOf(UndefinedStartBlockError) - } - }); - - - it('"startFiller" should ', async () => { - - await startFiller({...config, mode: Mode.Default} as any); - expect(broadcastMock.onBlockRangeReadyMessage).toBeCalled(); - - await startFiller({...config, mode: Mode.Replay} as any); - expect(broadcastMock.onBlockRangeReadyMessage).toBeCalled(); - - await startFiller({...config, mode: Mode.Test} as any); - expect(broadcastMock.onBlockRangeReadyMessage).toBeCalled(); - - try { - await startFiller({...config, mode: 'Foo'} as any); - } catch (error) { - expect(error).toBeInstanceOf(UnknownModeError); - } - }); -}); diff --git a/src/filler/filler.config.ts b/src/filler/filler.config.ts deleted file mode 100644 index 4d270d7..0000000 --- a/src/filler/filler.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; -import { AbisServiceConfig } from '../common/abis'; -import { BlockRangeScanConfig } from '../common/block-range-scanner'; -import { ContractReaderConfig } from '../common/blockchain'; -import { FeaturedConfig } from '../common/featured'; - -export type FillerConfig = { - broadcast: BroadcastConfig; - blockchain: { - endpoint: string; - chainId: string; - }; - contractReader: ContractReaderConfig; - scanner: BlockRangeScanConfig; - mongo: MongoConfig; - startBlock?: bigint; - endBlock?: bigint; - startFromHead?: boolean; - mode: string; - featured: FeaturedConfig; - abis: AbisServiceConfig; -}; diff --git a/src/filler/index.ts b/src/filler/index.ts deleted file mode 100644 index 408c581..0000000 --- a/src/filler/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './filler.config'; -export * from './filler.errors'; -export * from './filler.utils'; -export * from './start-filler'; diff --git a/src/filler/start-filler.ts b/src/filler/start-filler.ts deleted file mode 100644 index 41b303f..0000000 --- a/src/filler/start-filler.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { createBlockRangeTaskInput } from './filler.utils'; -import { Broadcast, log, MongoSource } from '@alien-worlds/api-core'; -import { setupAbis } from '../common/abis/abis.utils'; -import { setupBlockRangeScanner } from '../common/block-range-scanner'; -import { setupBlockState } from '../common/block-state'; -import { FillerConfig } from './filler.config'; -import { NoAbisError } from './filler.errors'; -import { - InternalBroadcastChannel, - InternalBroadcastClientName, - InternalBroadcastMessageName, -} from '../internal-broadcast/internal-broadcast.enums'; -import { InternalBroadcastMessage } from '../internal-broadcast/internal-broadcast.message'; -import { BlockRangeBroadcastMessages } from '../internal-broadcast/messages/block-range-broadcast.messages'; -import { setupContractReader } from '../common/blockchain'; -import { FeaturedContractContent } from '../common/featured'; - -/** - * - * @param broadcastMessageMapper - * @param config - * @returns - */ -export const startFiller = async (config: FillerConfig) => { - const { mode } = config; - - log(`Filler "${mode}" mode ... [starting]`); - - const broadcast = await Broadcast.createClient({ - ...config.broadcast, - clientName: InternalBroadcastClientName.Filler, - }); - const mongo = await MongoSource.create(config.mongo); - const contractReader = await setupContractReader(config.contractReader, mongo); - const abis = await setupAbis(mongo, config.abis, config.featured); - const blockState = await setupBlockState(mongo); - const scanner = await setupBlockRangeScanner(mongo, config.scanner); - const featured = new FeaturedContractContent(config.featured); - - // fetch latest abis to make sure that the blockchain data will be correctly deserialized - log(` * Fetch featured contracts details ... [starting]`); - await contractReader.readContracts(featured.listContracts()); - log(` * Fetch featured contracts details ... [ready]`); - - // fetch latest abis to make sure that the blockchain data will be correctly deserialized - log(` * Fetch abis ... [starting]`); - const abisCount = (await abis.fetchAbis()).length; - log(` * Fetch abis ... [ready]`); - - if (abisCount === 0) { - throw new NoAbisError(); - } - - try { - // Listen for block-range messages - broadcast.onMessage( - InternalBroadcastChannel.BlockRange, - async (message: InternalBroadcastMessage) => { - // In the case of further block-range processes (e.g. after a process reset or creating additional ones), - // send a task to all block-range processes. - const input = await createBlockRangeTaskInput(blockState, scanner, config); - if (message.content.name === InternalBroadcastMessageName.BlockRangeReady) { - broadcast.sendMessage( - BlockRangeBroadcastMessages.createBlockRangeTaskMessage(input) - ); - } - } - ); - await broadcast.connect(); - - const input = await createBlockRangeTaskInput(blockState, scanner, config); - // Everything is ready, send a task to block-range processes - broadcast.sendMessage(BlockRangeBroadcastMessages.createBlockRangeTaskMessage(input)); - } catch (error) { - log(error); - } - - log(`Filler ${mode} mode ... [ready]`); -}; diff --git a/src/filter/deserialized-block.ts b/src/filter/deserialized-block.ts new file mode 100644 index 0000000..b148783 --- /dev/null +++ b/src/filter/deserialized-block.ts @@ -0,0 +1,72 @@ +import { + Abi, + Delta, + SignedBlock, + SignedBlockJson, + Trace, +} from '../common/blockchain'; +import { TraceJson } from '../common/blockchain/contract/trace'; +import { DeltaJson } from '../common/blockchain/contract/delta'; +import { deserializeMessage } from '../reader'; +import { Block, BlockNumberWithId } from '../common/blockchain/block-reader/block'; + +export class DeserializedBlock { + public static create(block: Block, abi: Abi): DeserializedBlock { + const { head, lastIrreversible, prevBlock, thisBlock } = block; + const types = abi.getTypesMap(); + let traces: Trace[] = []; + let deltas: Delta[] = []; + let signedBlock: SignedBlock; + + if (block.block && block.block.length > 0) { + const deserializedBlock = deserializeMessage( + 'signed_block', + block.block, + types + ); + signedBlock = SignedBlock.create(deserializedBlock); + } + + if (block.traces && block.traces.length > 0) { + const tracesByType = deserializeMessage<[[string, TraceJson]]>( + 'transaction_trace[]', + block.traces, + types + ); + traces = tracesByType.map(([shipMessageName, traceJson]) => + Trace.create(shipMessageName, traceJson) + ); + } + + if (block.deltas && block.deltas.length > 0) { + const deltasByType = deserializeMessage<[[string, DeltaJson]]>( + 'table_delta[]', + block.deltas, + types + ); + deltas = deltasByType.map(([shipMessageName, deltaJson]) => + Delta.create(shipMessageName, deltaJson) + ); + } + + return new DeserializedBlock( + head, + thisBlock, + prevBlock, + lastIrreversible, + signedBlock, + traces, + deltas + ); + } + + private constructor( + public readonly head: BlockNumberWithId, + public readonly thisBlock: BlockNumberWithId, + public readonly prevBlock: BlockNumberWithId, + public readonly lastIrreversible: BlockNumberWithId, + public readonly block: SignedBlock, + public readonly traces: Trace[], + public readonly deltas: Delta[] + ) {} +} diff --git a/src/filter/filter.consts.ts b/src/filter/filter.consts.ts new file mode 100644 index 0000000..56baf83 --- /dev/null +++ b/src/filter/filter.consts.ts @@ -0,0 +1 @@ +export const filterWorkerLoaderPath = `${__dirname}/filter.worker-loader`; diff --git a/src/filter/filter.runner.ts b/src/filter/filter.runner.ts new file mode 100644 index 0000000..330d2c6 --- /dev/null +++ b/src/filter/filter.runner.ts @@ -0,0 +1,93 @@ +import { log } from '@alien-worlds/api-core'; +import { WorkerMessage, WorkerPool } from '../common/workers'; +import { FilterAddons, FilterConfig } from './filter.types'; +import { filterWorkerLoaderPath } from './filter.consts'; +import { BlockNotFoundError } from '../reader/unprocessed-block-queue/unprocessed-block-queue.errors'; +import { UnprocessedBlockQueue, UnprocessedBlockQueueReader } from '../reader'; +import { BlockJson } from '../common/blockchain/block-reader/block'; + +export class FilterRunner { + public static async create(config: FilterConfig, addons: FilterAddons) { + const { workers } = config; + const { matchers } = addons || {}; + const blocks = await UnprocessedBlockQueue.create( + config.mongo + ); + + const workerPool = await WorkerPool.create({ + ...workers, + sharedData: { config, matchers }, + workerLoaderPath: filterWorkerLoaderPath, + }); + const runner = new FilterRunner(workerPool, blocks); + + workerPool.onWorkerRelease(() => runner.next()); + + log(` * Worker Pool (max ${workerPool.workerMaxCount} workers) ... [ready]`); + + return runner; + } + + private interval: NodeJS.Timeout; + private loop: boolean; + private transitionHandler: (...args: unknown[]) => void | Promise; + + constructor( + private workerPool: WorkerPool, + private blocks: UnprocessedBlockQueueReader + ) { + this.interval = setInterval(async () => { + if (this.workerPool.hasActiveWorkers() === false) { + log(`All workers are available, checking if there blocks to parse...`); + this.next(); + } + }, 5000); + } + + public onTransition(handler: (...args: unknown[]) => void | Promise) { + this.transitionHandler = handler; + } + + public async next() { + const { workerPool, blocks } = this; + + // block multiple requests + if (this.loop) { + return; + } + + this.loop = true; + + while (this.loop) { + if (workerPool.hasAvailableWorker()) { + const { content: block, failure } = await blocks.next(); + if (failure) { + if (failure.error instanceof BlockNotFoundError) { + log(`No blocks to deserialize found....`); + } else { + log(failure.error); + } + this.loop = false; + } else { + const worker = await workerPool.getWorker(); + worker.onMessage(async (message: WorkerMessage) => { + if (message.isTaskRejected()) { + log(message.error); + } else if (message.isTaskResolved() && this.transitionHandler) { + this.transitionHandler(); + } + workerPool.releaseWorker(message.workerId); + }); + worker.onError((id, error) => { + log(error); + workerPool.releaseWorker(id); + }); + + worker.run(block.toJson()); + } + } else { + this.loop = false; + } + } + } +} diff --git a/src/filter/filter.types.ts b/src/filter/filter.types.ts new file mode 100644 index 0000000..e49c281 --- /dev/null +++ b/src/filter/filter.types.ts @@ -0,0 +1,32 @@ +import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; +import { FeaturedConfig, FeaturedMatchers } from '../common/featured'; +import { ProcessorTaskQueueConfig } from '../processor/processor-task-queue/processor-task-queue.config'; +import { WorkersConfig } from '../common/workers'; +import { AbisConfig } from '../common/abis'; +import { ContractReaderConfig } from '../common/blockchain'; + +export type FilterSharedData = { + config: FilterConfig; +}; + +export type FilterCommandOptions = { + threads: number; + mode: string; +}; + +export type FilterConfig = { + mode: string; + broadcast: BroadcastConfig; + workers: WorkersConfig; + featured: FeaturedConfig; + abis: AbisConfig; + contractReader: ContractReaderConfig; + mongo: MongoConfig; + queue: ProcessorTaskQueueConfig; + [key: string]: unknown; +}; + +export type FilterAddons = { + matchers?: FeaturedMatchers; + [key: string]: unknown; +}; diff --git a/src/block-range/block-range.utils.ts b/src/filter/filter.utils.ts similarity index 61% rename from src/block-range/block-range.utils.ts rename to src/filter/filter.utils.ts index d0202bb..f1a7665 100644 --- a/src/block-range/block-range.utils.ts +++ b/src/filter/filter.utils.ts @@ -1,8 +1,5 @@ import { log } from '@alien-worlds/api-core'; import { Serialize } from 'eosjs'; -import { Mode } from '../common/common.enums'; -import { BlockRangeTaskData } from '../common/common.types'; -import { InternalBroadcastMessage } from '../internal-broadcast'; type DeltaAllocation = { code: string; @@ -45,25 +42,3 @@ export const extractValues = (value: string): Set => { } return result; }; - -export const logTaskInfo = (message: InternalBroadcastMessage) => { - const { - content: { - data: { mode, startBlock, endBlock, scanKey }, - }, - } = message; - const info: { - mode?: string; - startBlock: string; - endBlock: string; - scanKey?: string; - } = { - mode, - startBlock: startBlock.toString(), - endBlock: endBlock.toString(), - }; - if (mode === Mode.Replay) { - info.scanKey = scanKey; - } - log(`Received block range task ${JSON.stringify(info)}`); -}; diff --git a/src/filter/filter.worker-loader.ts b/src/filter/filter.worker-loader.ts new file mode 100644 index 0000000..cac25ab --- /dev/null +++ b/src/filter/filter.worker-loader.ts @@ -0,0 +1,62 @@ +import { MongoSource } from '@alien-worlds/api-core'; +import { Worker } from '../common/workers'; +import { DefaultWorkerLoader } from '../common/workers/worker-loader'; +import { FilterSharedData } from './filter.types'; +import { + FeaturedContractContent, + FeaturedDelta, + FeaturedTrace, +} from '../common/featured'; +import { ContractReader } from '../common/blockchain'; +import { Abis } from '../common/abis'; +import { ProcessorTaskQueue } from '../processor/processor-task-queue'; +import FilterWorker from './filter.worker'; +import { ShipAbis } from '../common/ship/ship-abis'; + +export default class FilterWorkerLoader extends DefaultWorkerLoader { + private featuredTraces: FeaturedTrace[]; + private featuredDeltas: FeaturedDelta[]; + private contractReader: ContractReader; + private processorTaskQueue: ProcessorTaskQueue; + private abis: Abis; + private shipAbis: ShipAbis; + + public async setup(sharedData: FilterSharedData): Promise { + super.setup(sharedData); + const { + config: { mongo, featured, abis, contractReader, queue }, + } = sharedData; + const { traces, deltas } = new FeaturedContractContent(featured).toJson(); + + const mongoSource = await MongoSource.create(mongo); + this.abis = await Abis.create(mongoSource, abis.service, featured); + this.contractReader = await ContractReader.create(contractReader, mongoSource); + this.processorTaskQueue = await ProcessorTaskQueue.create(mongoSource, true, queue); + this.shipAbis = await ShipAbis.create(mongoSource); + this.featuredDeltas = deltas; + this.featuredTraces = traces; + } + + public async load(): Promise { + const { + abis, + shipAbis, + contractReader, + featuredTraces, + featuredDeltas, + processorTaskQueue, + sharedData, + } = this; + return new FilterWorker( + { + shipAbis, + abis, + contractReader, + featuredTraces, + featuredDeltas, + processorTaskQueue, + }, + sharedData + ); + } +} diff --git a/src/filter/filter.worker.ts b/src/filter/filter.worker.ts new file mode 100644 index 0000000..baa8925 --- /dev/null +++ b/src/filter/filter.worker.ts @@ -0,0 +1,246 @@ +import { log } from '@alien-worlds/api-core'; +import { + FeaturedDelta, + FeaturedDeltas, + FeaturedTrace, + FeaturedTraces, +} from '../common/featured'; +import { Worker } from '../common/workers'; +import { DeserializedBlock } from './deserialized-block'; +import { Abis } from '../common/abis'; +import { ContractReader } from '../common/blockchain'; +import { isSetAbiAction } from '../common/common.utils'; +import { ProcessorTask, ProcessorTaskQueue } from '../processor/processor-task-queue'; +import { FilterSharedData } from './filter.types'; +import { extractAllocationFromDeltaRow } from './filter.utils'; +import { Block, BlockJson } from '../common/blockchain/block-reader/block'; +import { ShipAbis } from '../common/ship/ship-abis'; + +export default class FilterWorker extends Worker { + protected shipAbis: ShipAbis; + protected abis: Abis; + protected contractReader: ContractReader; + protected processorTaskQueue: ProcessorTaskQueue; + protected featuredTraces: FeaturedTrace[]; + protected featuredDeltas: FeaturedDelta[]; + + constructor( + components: { + shipAbis: ShipAbis; + abis: Abis; + contractReader: ContractReader; + processorTaskQueue: ProcessorTaskQueue; + featuredTraces: FeaturedTrace[]; + featuredDeltas: FeaturedDelta[]; + }, + sharedData: FilterSharedData + ) { + super(); + const { + abis, + contractReader, + featuredTraces, + featuredDeltas, + processorTaskQueue, + shipAbis, + } = components; + this.shipAbis = shipAbis; + this.abis = abis; + this.contractReader = contractReader; + this.processorTaskQueue = processorTaskQueue; + this.featuredTraces = featuredTraces; + this.featuredDeltas = featuredDeltas; + this.sharedData = sharedData; + } + + public async createActionProcessorTasks( + deserializedBlock: DeserializedBlock + ): Promise { + const { + featuredTraces, + abis, + contractReader, + sharedData: { config }, + } = this; + const { + traces, + thisBlock, + block: { timestamp }, + prevBlock, + } = deserializedBlock; + const featured = new FeaturedTraces(featuredTraces); + const list: ProcessorTask[] = []; + + for (const trace of traces) { + const { id, actionTraces, shipTraceMessageName } = trace; + + for (const actionTrace of actionTraces) { + const { + act: { account, name }, + } = actionTrace; + + const matchedTraces = await featured.get({ + shipTraceMessageName, + action: name, + contract: account, + }); + + if (matchedTraces.length > 0) { + try { + // If the block in which the contract was created cannot be found or + // its index is higher than the current block number, skip it, + // the contract did not exist at that time + const initBlockNumber = await contractReader.getInitialBlockNumber(account); + if (initBlockNumber === -1n || initBlockNumber > thisBlock.blockNumber) { + continue; + } + + // get ABI from the database and if it does not exist, try to fetch it + const abi = await abis.getAbi(thisBlock.blockNumber, account, true); + if (!abi && isSetAbiAction(account, name) === false) { + log( + `Action-trace {block_number: ${thisBlock.blockNumber}, account: ${account}, name: ${name}}: no ABI was found. This can be a problem in reading the content.` + ); + } + list.push( + ProcessorTask.createActionProcessorTask( + abi ? abi.hex : '', + config.mode, + shipTraceMessageName, + id, + actionTrace, + thisBlock.blockNumber, + timestamp, + thisBlock.blockNumber <= prevBlock.blockNumber + ) + ); + } catch (error) { + log(`Action-trace not handled`, error); + } + } + } + } + + return list; + } + + public async createDeltaProcessorTasks( + deserializedBlock: DeserializedBlock + ): Promise { + const { + featuredDeltas, + abis, + contractReader, + sharedData: { config }, + } = this; + const { + deltas, + thisBlock, + block: { timestamp }, + prevBlock, + } = deserializedBlock; + const list: ProcessorTask[] = []; + const featured = new FeaturedDeltas(featuredDeltas); + + for (const delta of deltas) { + const { name, shipDeltaMessageName } = delta; + const allocations = delta.rows.map(row => extractAllocationFromDeltaRow(row.data)); + + for (let i = 0; i < delta.rows.length; i++) { + const row = delta.rows[i]; + const allocation = allocations[i]; + + if (!allocation) { + // contract allocation cannot be extracted + // The contract may not contain tables or may be corrupted + continue; + } + + const { code, scope, table } = allocation; + const matchedDeltas = await featured.get({ + shipDeltaMessageName, + name, + code, + scope, + table, + }); + + if (matchedDeltas.length > 0) { + try { + // If the block in which the contract was created cannot be found or + // its index is higher than the current block number, skip it, + // the contract did not exist at that time + const initBlockNumber = await contractReader.getInitialBlockNumber(code); + if (initBlockNumber === -1n || initBlockNumber > thisBlock.blockNumber) { + continue; + } + + // get ABI from the database and if it does not exist, try to fetch it + const abi = await abis.getAbi(thisBlock.blockNumber, code, true); + if (!abi) { + log( + `Delta {block_number: ${thisBlock.blockNumber}, code: ${code}, scope: ${scope}, table: ${table}}: no ABI was found. This can be a problem in reading the content.` + ); + } + list.push( + ProcessorTask.createDeltaProcessorTask( + abi ? abi.hex : '', + config.mode, + shipDeltaMessageName, + name, + code, + scope, + table, + thisBlock.blockNumber, + timestamp, + row, + thisBlock.blockNumber <= prevBlock.blockNumber + ) + ); + } catch (error) { + log(`Delta (table row) not handled`, error); + } + } + } + } + + return list; + } + + public async run(json: BlockJson): Promise { + try { + const { processorTaskQueue, shipAbis } = this; + const { content: abi, failure } = await shipAbis.getAbi(json.abi_version); + + if (failure) { + log('SHiP Abi not found.'); + this.reject(failure.error); + } + + const deserializedBlock = DeserializedBlock.create(Block.fromJson(json), abi); + const { + thisBlock: { blockNumber }, + } = deserializedBlock; + const [actionProcessorTasks, deltaProcessorTasks] = await Promise.all([ + this.createActionProcessorTasks(deserializedBlock), + this.createDeltaProcessorTasks(deserializedBlock), + ]); + const tasks = [...actionProcessorTasks, ...deltaProcessorTasks]; + + if (tasks.length > 0) { + log( + `Block #${blockNumber} contains ${actionProcessorTasks.length} actions and ${deltaProcessorTasks.length} deltas to process (${tasks.length} tasks in total).` + ); + processorTaskQueue.addTasks(tasks); + } else { + log( + `The block (${blockNumber}) does not contain actions and deltas that could be processed.` + ); + } + + this.resolve(); + } catch (error) { + this.reject(error); + } + } +} diff --git a/src/filter/index.ts b/src/filter/index.ts new file mode 100644 index 0000000..d4633ce --- /dev/null +++ b/src/filter/index.ts @@ -0,0 +1,7 @@ +export * from './deserialized-block'; +export * from './filter.consts'; +export * from './filter.types'; +export * from './filter.worker-loader'; +export * from './filter.worker'; +export * from './filter.runner'; +export * from './start-filter'; diff --git a/src/filter/start-filter.ts b/src/filter/start-filter.ts new file mode 100644 index 0000000..35d109a --- /dev/null +++ b/src/filter/start-filter.ts @@ -0,0 +1,46 @@ +import { Broadcast, log } from '@alien-worlds/api-core'; +import { FilterAddons, FilterConfig } from './filter.types'; +import { + InternalBroadcastChannel, + InternalBroadcastClientName, + InternalBroadcastMessageName, + ProcessorBroadcastMessage, +} from '../broadcast'; +import { InternalBroadcastMessage } from '../broadcast/internal-broadcast.message'; +import { FilterRunner } from './filter.runner'; +import { FilterBroadcastMessage } from '../broadcast/messages/filter-broadcast.message'; + +/** + * + * @param featuredContent + * @param broadcastMessageMapper + * @param config + */ +export const startFilter = async (config: FilterConfig, addons?: FilterAddons) => { + log(`Filter ... [starting]`); + const broadcast = await Broadcast.createClient({ + ...config.broadcast, + clientName: InternalBroadcastClientName.Filter, + }); + const runner = await FilterRunner.create(config, addons); + runner.onTransition(() => { + broadcast.sendMessage(ProcessorBroadcastMessage.refresh()); + }); + + broadcast.onMessage( + InternalBroadcastChannel.Filter, + async (message: InternalBroadcastMessage) => { + if (message.content.name === InternalBroadcastMessageName.FilterRefresh) { + runner.next(); + } + } + ); + await broadcast.connect(); + // Everything is ready, notify bootstrap that the process is ready to work + broadcast.sendMessage(FilterBroadcastMessage.ready()); + + // start filter in case the queue already contains blocks + runner.next(); + + log(`Filter ... [ready]`); +}; diff --git a/src/index.ts b/src/index.ts index 471bae5..ad0dabb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,8 @@ -export * from './config'; export * from './api'; +export * from './bootstrap'; +export * from './common'; +export * from './config'; +export * from './filter'; +export * from './broadcast'; export * from './processor'; -export * from './block-range'; -export * from './filler'; -export * from './internal-broadcast'; -export * from './common/abis'; -export * from './common/block-range-scanner'; -export * from './common/block-state'; -export * from './common/blockchain'; -export * from './common/featured'; -export * from './common/processor-task-queue'; -export * from './common/workers'; -export * from './common/common.enums'; -export * from './common/common.errors'; -export * from './common/common.types'; -export * from './common/common.utils'; +export * from './reader'; diff --git a/src/internal-broadcast/index.ts b/src/internal-broadcast/index.ts deleted file mode 100644 index 10842e6..0000000 --- a/src/internal-broadcast/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './internal-broadcast.enums'; -export * from './internal-broadcast.message'; -export * from './messages/block-range-broadcast.messages'; -export * from './messages/processor-broadcast.messages'; -export * from './messages/processor-queue-broadcast.messages'; diff --git a/src/internal-broadcast/internal-broadcast.enums.ts b/src/internal-broadcast/internal-broadcast.enums.ts deleted file mode 100644 index 5d6d7cb..0000000 --- a/src/internal-broadcast/internal-broadcast.enums.ts +++ /dev/null @@ -1,26 +0,0 @@ -export enum InternalBroadcastChannel { - Filler = 'filler', - BlockRange = 'block-range', - Processor = 'processor', - ProcessorTasksQueue = 'processor-tasks-queue', - ExternalBroadcast = 'external-broadcast', -} - -export enum InternalBroadcastClientName { - Filler = 'filler', - BlockRange = 'block-range', - BlockRangeDefaultModeTask = 'block-range-default-mode-task', - BlockRangeReplayModeTask = 'block-range-replay-mode-task', - Processor = 'processor', - ProcessorTask = 'processor-task', - ProcessorTasksQueue = 'processor-tasks-queue', - ExternalBroadcast = 'external-broadcast', -} - -export enum InternalBroadcastMessageName { - BlockRangeReady = 'block-range-ready', - BlockRangeTask = 'block-range-task', - Processor = 'processor', - ProcessorReady = 'processor-ready', - ProcessorTasksQueueUpdate = 'processor-tasks-queue-update', -} diff --git a/src/internal-broadcast/messages/block-range-broadcast.messages.ts b/src/internal-broadcast/messages/block-range-broadcast.messages.ts deleted file mode 100644 index de019d7..0000000 --- a/src/internal-broadcast/messages/block-range-broadcast.messages.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { BroadcastTcpMessageType } from '@alien-worlds/api-core'; -import { BlockRangeTaskData } from '../../common/common.types'; -import { - InternalBroadcastChannel, - InternalBroadcastMessageName, -} from '../internal-broadcast.enums'; - -/** - * Message content - */ -export class BlockRangeBroadcastMessages { - public static createBlockRangeTaskMessage(data: BlockRangeTaskData) { - return { - channel: InternalBroadcastChannel.BlockRange, - name: InternalBroadcastMessageName.BlockRangeTask, - type: BroadcastTcpMessageType.Data, - data, - }; - } - - public static createBlockRangeReadyMessage() { - return { - channel: InternalBroadcastChannel.BlockRange, - name: InternalBroadcastMessageName.BlockRangeReady, - type: BroadcastTcpMessageType.Data, - }; - } -} diff --git a/src/internal-broadcast/messages/processor-queue-broadcast.messages.ts b/src/internal-broadcast/messages/processor-queue-broadcast.messages.ts deleted file mode 100644 index 26a85fa..0000000 --- a/src/internal-broadcast/messages/processor-queue-broadcast.messages.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { BroadcastTcpMessageType } from '@alien-worlds/api-core'; -import { - InternalBroadcastChannel, - InternalBroadcastMessageName, -} from '../internal-broadcast.enums'; - -/** - * Message content - */ -export class ProcessorQueueBroadcastMessages { - public static createUpdateMessage() { - return { - channel: InternalBroadcastChannel.Processor, - name: InternalBroadcastMessageName.ProcessorTasksQueueUpdate, - type: BroadcastTcpMessageType.Data, - }; - } -} diff --git a/src/processor/index.ts b/src/processor/index.ts index 72f1ace..d7bb2a4 100644 --- a/src/processor/index.ts +++ b/src/processor/index.ts @@ -4,11 +4,6 @@ export * from './processors/delta.processor'; export * from './processors/delta.processor.input'; export * from './processors/processor'; -export * as SetAbiProcessor from './processors/setabi/set-abi.processor'; -export * from './processors/setabi/set-abi-processor.input'; -export * from './processors/setabi/set-abi.types'; - -export * from './processor.config'; export * from './processor.types'; export * from './processor.enum'; export * from './processor.errors'; diff --git a/src/common/processor-task-queue/data-sources/processor-task.source.ts b/src/processor/processor-task-queue/data-sources/processor-task.source.ts similarity index 100% rename from src/common/processor-task-queue/data-sources/processor-task.source.ts rename to src/processor/processor-task-queue/data-sources/processor-task.source.ts diff --git a/src/common/processor-task-queue/data-sources/unsuccessful-processor-task.source.ts b/src/processor/processor-task-queue/data-sources/unsuccessful-processor-task.source.ts similarity index 100% rename from src/common/processor-task-queue/data-sources/unsuccessful-processor-task.source.ts rename to src/processor/processor-task-queue/data-sources/unsuccessful-processor-task.source.ts diff --git a/src/common/processor-task-queue/index.ts b/src/processor/processor-task-queue/index.ts similarity index 83% rename from src/common/processor-task-queue/index.ts rename to src/processor/processor-task-queue/index.ts index e00229f..964e5f6 100644 --- a/src/common/processor-task-queue/index.ts +++ b/src/processor/processor-task-queue/index.ts @@ -1,6 +1,5 @@ export * from './processor-task-queue'; export * from './data-sources/processor-task.source'; export * from './data-sources/unsuccessful-processor-task.source'; -export * from './processor-task-queue.utils'; export * from './processor-task'; export * from './processor-task.types'; diff --git a/src/common/processor-task-queue/processor-task-queue.config.ts b/src/processor/processor-task-queue/processor-task-queue.config.ts similarity index 100% rename from src/common/processor-task-queue/processor-task-queue.config.ts rename to src/processor/processor-task-queue/processor-task-queue.config.ts diff --git a/src/common/processor-task-queue/processor-task-queue.ts b/src/processor/processor-task-queue/processor-task-queue.ts similarity index 65% rename from src/common/processor-task-queue/processor-task-queue.ts rename to src/processor/processor-task-queue/processor-task-queue.ts index 894d876..bc63af7 100644 --- a/src/common/processor-task-queue/processor-task-queue.ts +++ b/src/processor/processor-task-queue/processor-task-queue.ts @@ -1,14 +1,46 @@ -import { DataSourceBulkWriteError, log, MongoSource } from '@alien-worlds/api-core'; +import { + DataSourceBulkWriteError, + log, + MongoConfig, + MongoSource, +} from '@alien-worlds/api-core'; import { ProcessorTaskSource } from './data-sources/processor-task.source'; import { ProcessorTask } from './processor-task'; import { UnsuccessfulProcessorTaskSource } from './data-sources/unsuccessful-processor-task.source'; import { ProcessorTaskQueueConfig } from './processor-task-queue.config'; +import { ErrorJson } from '../../common/workers/worker-message'; export class ProcessorTaskQueue { + public static async create( + mongo: MongoSource | MongoConfig, + onlyAdd: boolean, + queueConfig?: ProcessorTaskQueueConfig + ) { + log(` * Processor Queue ... [starting]`); + + let state: ProcessorTaskQueue; + + if (mongo instanceof MongoSource) { + if (!mongo.client) { + throw new Error( + 'ProcessorTaskQueue requires MongoSource to provide a mongo client. Create Mongo Source using "MongoSource.create()"' + ); + } + + state = new ProcessorTaskQueue(mongo, queueConfig, onlyAdd); + } else { + const mongoSource = await MongoSource.create(mongo); + state = new ProcessorTaskQueue(mongoSource, queueConfig, onlyAdd); + } + + log(` * Processor Queue ... [ready]`); + return state; + } + private source: ProcessorTaskSource; private unsuccessfulSource: UnsuccessfulProcessorTaskSource; - constructor( + private constructor( mongo: MongoSource, config: ProcessorTaskQueueConfig, private onlyAdd = false @@ -48,7 +80,10 @@ export class ProcessorTaskQueue { } } - public async stashUnsuccessfulTask(task: ProcessorTask, error: Error): Promise { + public async stashUnsuccessfulTask( + task: ProcessorTask, + error: ErrorJson | Error + ): Promise { try { const { message, stack } = error; const dto = task.toDocument(); diff --git a/src/common/processor-task-queue/processor-task.ts b/src/processor/processor-task-queue/processor-task.ts similarity index 97% rename from src/common/processor-task-queue/processor-task.ts rename to src/processor/processor-task-queue/processor-task.ts index 1e2adbd..1b21329 100644 --- a/src/common/processor-task-queue/processor-task.ts +++ b/src/processor/processor-task-queue/processor-task.ts @@ -5,7 +5,7 @@ import { parseToBigInt, removeUndefinedProperties, } from '@alien-worlds/api-core'; -import { ActionTrace, DeltaRow } from '../blockchain/block-content'; +import { ActionTrace, DeltaRow } from '../../common/blockchain/contract'; import { DeltaProcessorContentModel, ProcessorTaskDocument, @@ -107,7 +107,7 @@ export class ProcessorTask { hash, blockNumber, blockTimestamp, - isFork, + isFork ); } diff --git a/src/common/processor-task-queue/processor-task.types.ts b/src/processor/processor-task-queue/processor-task.types.ts similarity index 86% rename from src/common/processor-task-queue/processor-task.types.ts rename to src/processor/processor-task-queue/processor-task.types.ts index 4da2527..c7c187d 100644 --- a/src/common/processor-task-queue/processor-task.types.ts +++ b/src/processor/processor-task-queue/processor-task.types.ts @@ -1,11 +1,11 @@ import { MongoDB } from '@alien-worlds/api-core'; -import { ActionTraceModel } from '../blockchain/block-content/action-trace'; -import { DeltaRowModel } from '../blockchain/block-content/delta'; +import { ActionTraceModel } from '../../common/blockchain/contract/action-trace'; +import { DeltaRowModel } from '../../common/blockchain/contract/delta'; export type ProcessorTaskError = { message: string; stack: string; -} +}; export type ProcessorTaskDocument = { _id?: MongoDB.ObjectId; diff --git a/src/processor/processor.config.ts b/src/processor/processor.config.ts deleted file mode 100644 index 9417e14..0000000 --- a/src/processor/processor.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; -import { FeaturedConfig, FeaturedMatchers } from '../common/featured'; -import { ProcessorTaskQueueConfig } from '../common/processor-task-queue/processor-task-queue.config'; -import { WorkersConfig } from '../common/workers'; - -export type ProcessorConfig = { - broadcast: BroadcastConfig; - workers: WorkersConfig; - featured: FeaturedConfig; - mongo: MongoConfig; - queue: ProcessorTaskQueueConfig; - sharedData?: unknown; - customProcessorLoaderPath?: string; - [key: string]: unknown; -}; - -export type ProcessorAddons = { - matchers?: FeaturedMatchers; - [key: string]: unknown; -}; diff --git a/src/processor/processor.runner.ts b/src/processor/processor.runner.ts index 8b8b1d0..f6ca242 100644 --- a/src/processor/processor.runner.ts +++ b/src/processor/processor.runner.ts @@ -4,10 +4,9 @@ import { ProcessorTaskQueue, ProcessorTask, ProcessorTaskModel, - setupProcessorTaskQueue, -} from '../common/processor-task-queue'; -import { createWorkerPool, WorkerMessage, WorkerPool } from '../common/workers'; -import { ProcessorAddons, ProcessorConfig } from './processor.config'; +} from './processor-task-queue'; +import { WorkerMessage, WorkerPool } from '../common/workers'; +import { ProcessorAddons, ProcessorConfig } from './processor.types'; import { processorWorkerLoaderPath } from './processor.consts'; export class ProcessorRunner { @@ -17,11 +16,11 @@ export class ProcessorRunner { private static async creator(config: ProcessorConfig, addons: ProcessorAddons) { const { workers } = config; const { matchers } = addons; - const queue = await setupProcessorTaskQueue(config.mongo, false, config.queue); + const queue = await ProcessorTaskQueue.create(config.mongo, false, config.queue); const featuredContent = new FeaturedContractContent(config.featured, matchers); - const workerPool = await createWorkerPool({ + const workerPool = await WorkerPool.create({ ...workers, - workerLoaderPath: config.customProcessorLoaderPath || processorWorkerLoaderPath, + workerLoaderPath: config.processorLoaderPath || processorWorkerLoaderPath, }); const runner = new ProcessorRunner(workerPool, queue, featuredContent); @@ -82,22 +81,24 @@ export class ProcessorRunner { log( `Worker #${worker.id} has completed (successfully) work on the task "${task.id}". Worker to be released.` ); - } else { + workerPool.releaseWorker(message.workerId); + } else if (message.isTaskRejected()) { queue.stashUnsuccessfulTask(task, message.error); log(message.error); log( `Worker #${worker.id} has completed (unsuccessfully) work on the task "${task.id}". The task was stashed for later analysis. Worker to be released.` ); + workerPool.releaseWorker(message.workerId); + } else { + // task in progress } - // release the worker when he has finished his work - workerPool.releaseWorker(message.workerId); }); - worker.onError(error => { + worker.onError((id, error) => { log(error); // stash failed task and release the worker in case of an error queue.stashUnsuccessfulTask(task, error); - workerPool.releaseWorker(worker.id); + workerPool.releaseWorker(id); }); // start worker worker.run(task); diff --git a/src/processor/processor.types.ts b/src/processor/processor.types.ts index 1f36b5f..a834988 100644 --- a/src/processor/processor.types.ts +++ b/src/processor/processor.types.ts @@ -1,38 +1,25 @@ -import { ProcessorConfig } from './processor.config'; +import { MongoConfig, BroadcastConfig } from '@alien-worlds/api-core'; +import { FeaturedConfig, FeaturedMatchers } from '../common/featured'; +import { ProcessorTaskQueueConfig } from './processor-task-queue/processor-task-queue.config'; +import { WorkersConfig } from '../common/workers'; -export type DeltaMessageBufferData = { - shipDeltaMessageName: string; - name: string; - code: string; - scope: string; - table: string; - payer: string; - present: number; - primaryKey: bigint; - blockNumber: bigint; - blockTimestamp: Date; - data: Uint8Array; - dataHash: string; - label: string; +export type ProcessorCommandOptions = { + threads: number; }; -export type TraceMessageBufferData = { - blockNumber: bigint; - blockTimestamp: Date; - transactionId: string; - account: string; - name: string; - recvSequence: bigint; - globalSequence: bigint; - data: Uint8Array; - label: string; - shipTraceMessageName: string; - shipActionTraceMessageName: string; +export type ProcessorConfig = { + broadcast: BroadcastConfig; + workers: WorkersConfig; + featured: FeaturedConfig; + mongo: MongoConfig; + queue: ProcessorTaskQueueConfig; + processorLoaderPath?: string; + [key: string]: unknown; }; -export type ProcessorMessageContent = { - label: string; - data?: Uint8Array; +export type ProcessorAddons = { + matchers?: FeaturedMatchers; + [key: string]: unknown; }; export type ProcessorSharedData = { diff --git a/src/processor/processor.worker-loader.ts b/src/processor/processor.worker-loader.ts index 4297938..fae66f1 100644 --- a/src/processor/processor.worker-loader.ts +++ b/src/processor/processor.worker-loader.ts @@ -7,14 +7,12 @@ export default class ProcessorWorkerLoader extends DefaultWorkerLoader { private mongoSource: MongoSource; public async setup(sharedData: ProcessorSharedData): Promise { - const { - config: { mongo }, - } = sharedData; - this.mongoSource = await MongoSource.create(mongo); + super.setup(sharedData); + this.mongoSource = await MongoSource.create(sharedData.config.mongo); } - public async load(pointer: string, containerPath: string): Promise { + public async load(pointer: string): Promise { const { mongoSource } = this; - return super.load(pointer, containerPath, mongoSource); + return super.load(pointer, { mongoSource }); } } diff --git a/src/processor/processors/action-trace.processor.input.ts b/src/processor/processors/action-trace.processor.input.ts index 43e7f2b..312b426 100644 --- a/src/processor/processors/action-trace.processor.input.ts +++ b/src/processor/processors/action-trace.processor.input.ts @@ -3,7 +3,7 @@ import { AbisSerialize } from '../../common/abis/abis.serialize'; import { ActionProcessorContentModel, ProcessorTaskModel, -} from '../../common/processor-task-queue/processor-task.types'; +} from '../processor-task-queue/processor-task.types'; export class ActionTraceProcessorInput { public static create(model: ProcessorTaskModel) { diff --git a/src/processor/processors/action-trace.processor.ts b/src/processor/processors/action-trace.processor.ts index aefe5b7..2cd9ffb 100644 --- a/src/processor/processors/action-trace.processor.ts +++ b/src/processor/processors/action-trace.processor.ts @@ -1,17 +1,16 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Processor } from './processor'; import { ActionTraceProcessorInput } from './action-trace.processor.input'; -import { ProcessorTaskModel } from '../../common/processor-task-queue/processor-task.types'; -import { MongoSource } from '@alien-worlds/api-core'; +import { ProcessorTaskModel } from '../processor-task-queue/processor-task.types'; +import { ProcessorSharedData } from '../processor.types'; -export class ActionTraceProcessor extends Processor { +export class ActionTraceProcessor< + DataType = unknown, + SharedDataType = ProcessorSharedData +> extends Processor { protected input: ActionTraceProcessorInput; - constructor(protected mongoSource: MongoSource) { - super(); - } - - public async run(data: ProcessorTaskModel, sharedData: unknown): Promise { + public async run(data: ProcessorTaskModel): Promise { this.input = ActionTraceProcessorInput.create(data); } } diff --git a/src/processor/processors/delta.processor.input.ts b/src/processor/processors/delta.processor.input.ts index 360c6eb..249ac01 100644 --- a/src/processor/processors/delta.processor.input.ts +++ b/src/processor/processors/delta.processor.input.ts @@ -4,7 +4,7 @@ import { AbisSerialize } from '../../common/abis/abis.serialize'; import { DeltaProcessorContentModel, ProcessorTaskModel, -} from '../../common/processor-task-queue/processor-task.types'; +} from '../processor-task-queue/processor-task.types'; export class DeltaProcessorInput { public static create(model: ProcessorTaskModel) { diff --git a/src/processor/processors/delta.processor.ts b/src/processor/processors/delta.processor.ts index e05ed99..f877b5e 100644 --- a/src/processor/processors/delta.processor.ts +++ b/src/processor/processors/delta.processor.ts @@ -1,17 +1,16 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { MongoSource } from '@alien-worlds/api-core'; -import { ProcessorTaskModel } from '../../common/processor-task-queue/processor-task.types'; +import { ProcessorTaskModel } from '../processor-task-queue/processor-task.types'; import { DeltaProcessorInput } from './delta.processor.input'; import { Processor } from './processor'; +import { ProcessorSharedData } from '../processor.types'; -export class DeltaProcessor extends Processor { +export class DeltaProcessor< + DataType, + SharedDataType = ProcessorSharedData +> extends Processor { protected input: DeltaProcessorInput; - constructor(protected mongoSource: MongoSource) { - super(); - } - - public async run(data: ProcessorTaskModel, sharedData: unknown): Promise { + public async run(data: ProcessorTaskModel): Promise { this.input = DeltaProcessorInput.create(data); } } diff --git a/src/processor/processors/index.ts b/src/processor/processors/index.ts index 1227eab..a09bbd6 100644 --- a/src/processor/processors/index.ts +++ b/src/processor/processors/index.ts @@ -1,4 +1,3 @@ -export * from './setabi'; export * from './action-trace.processor'; export * from './action-trace.processor.input'; export * from './delta.processor'; diff --git a/src/processor/processors/processor.ts b/src/processor/processors/processor.ts index fba0e58..e90dd72 100644 --- a/src/processor/processors/processor.ts +++ b/src/processor/processors/processor.ts @@ -1,6 +1,12 @@ -import { ProcessorTaskModel } from '../../common/processor-task-queue/processor-task.types'; +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { ProcessorTaskModel } from '../processor-task-queue/processor-task.types'; import { Worker } from '../../common/workers/worker'; +import { ProcessorSharedData } from '../processor.types'; -export abstract class Processor extends Worker { - public abstract run(data: ProcessorTaskModel, sharedData: unknown): Promise; +export class Processor< + SharedDataType = ProcessorSharedData +> extends Worker { + public run(data: ProcessorTaskModel): Promise { + throw new Error('Method not implemented'); + } } diff --git a/src/processor/processors/setabi/index.ts b/src/processor/processors/setabi/index.ts deleted file mode 100644 index f67147c..0000000 --- a/src/processor/processors/setabi/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * as SetAbiProcessor from './set-abi.processor'; -export * from './set-abi-processor.input'; -export * from './set-abi.types'; diff --git a/src/processor/processors/setabi/set-abi-processor.input.ts b/src/processor/processors/setabi/set-abi-processor.input.ts deleted file mode 100644 index bf10b4d..0000000 --- a/src/processor/processors/setabi/set-abi-processor.input.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Serialize } from 'eosjs'; -import { deserialize } from 'v8'; -import { - ActionProcessorContentModel, - ProcessorTaskModel, -} from '../../../common/processor-task-queue'; -import { SetAbiData } from './set-abi.types'; - -export class SetAbiProcessorInput { - public static create(model: ProcessorTaskModel) { - const { content: buffer, hash } = model; - const content: ActionProcessorContentModel = deserialize(buffer); - const { - actionTrace: { - act: { account, data, name }, - receipt: { recvSequence, globalSequence }, - }, - blockNumber, - blockTimestamp, - transactionId, - } = content; - - const sb = new Serialize.SerialBuffer({ - textEncoder: new TextEncoder(), - textDecoder: new TextDecoder(), - array: data, - }); - - const deserializedData: SetAbiData = { - account: sb.getName(), - abi: Buffer.from(sb.getBytes()).toString('hex').toUpperCase(), - }; - - return new SetAbiProcessorInput( - blockNumber, - blockTimestamp, - transactionId, - account, - name, - recvSequence, - globalSequence, - deserializedData, - hash - ); - } - - private constructor( - public readonly blockNumber: bigint, - public readonly blockTimestamp: Date, - public readonly transactionId: string, - public readonly account: string, - public readonly name: string, - public readonly recvSequence: bigint, - public readonly globalSequence: bigint, - public readonly data: SetAbiData, - public readonly dataHash: string - ) {} -} diff --git a/src/processor/processors/setabi/set-abi.processor.ts b/src/processor/processors/setabi/set-abi.processor.ts deleted file mode 100644 index 39ba2e5..0000000 --- a/src/processor/processors/setabi/set-abi.processor.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MongoSource } from '@alien-worlds/api-core'; -import { setupAbis } from '../../../common/abis'; -import { ProcessorTaskModel } from '../../../common/processor-task-queue'; -import { Processor } from '../processor'; -import { SetAbiProcessorInput } from './set-abi-processor.input'; - -export default class SetAbiProcessor extends Processor { - constructor(protected mongoSource: MongoSource) { - super(); - } - - public async run(input: ProcessorTaskModel): Promise { - try { - const { - data: { abi, account }, - blockNumber, - } = SetAbiProcessorInput.create(input); - - const abis = await setupAbis(this.mongoSource); - const isAdded = await abis.storeAbi(blockNumber, account, abi); - - if (isAdded) { - this.resolve(true); - } else { - this.reject( - new Error( - `ABI defined ${blockNumber.toString()} for account ${account} has not been stored in the database.` - ) - ); - } - } catch (error) { - this.reject(error); - } - } -} diff --git a/src/processor/processors/setabi/set-abi.types.ts b/src/processor/processors/setabi/set-abi.types.ts deleted file mode 100644 index 44eaf0b..0000000 --- a/src/processor/processors/setabi/set-abi.types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ProcessorConfig } from "../../processor.config"; - -export type SetAbiData = { - account: string; - abi: string; -}; - -export type SetAbiSharedData = { - config: ProcessorConfig; -}; diff --git a/src/processor/start-processor.ts b/src/processor/start-processor.ts index efff507..5baf540 100644 --- a/src/processor/start-processor.ts +++ b/src/processor/start-processor.ts @@ -1,12 +1,12 @@ import { Broadcast, log } from '@alien-worlds/api-core'; -import { ProcessorAddons, ProcessorConfig } from './processor.config'; +import { ProcessorAddons, ProcessorConfig } from './processor.types'; import { InternalBroadcastChannel, InternalBroadcastClientName, InternalBroadcastMessageName, - ProcessorBroadcastMessages, -} from '../internal-broadcast'; -import { InternalBroadcastMessage } from '../internal-broadcast/internal-broadcast.message'; + ProcessorBroadcastMessage, +} from '../broadcast'; +import { InternalBroadcastMessage } from '../broadcast/internal-broadcast.message'; import { ProcessorRunner } from './processor.runner'; /** @@ -29,16 +29,14 @@ export const startProcessor = async ( broadcast.onMessage( InternalBroadcastChannel.Processor, async (message: InternalBroadcastMessage) => { - if ( - message.content.name === InternalBroadcastMessageName.ProcessorTasksQueueUpdate - ) { + if (message.content.name === InternalBroadcastMessageName.ProcessorRefresh) { runner.next(); } } ); await broadcast.connect(); // Everything is ready, notify the block-range that the process is ready to work - broadcast.sendMessage(ProcessorBroadcastMessages.createProcessorReadyMessage()); + broadcast.sendMessage(ProcessorBroadcastMessage.ready()); // start processor in case the queue already contains tasks runner.next(); diff --git a/src/common/block-range-scanner/block-range-scan.mongo.source.ts b/src/reader/block-range-scanner/block-range-scan.mongo.source.ts similarity index 98% rename from src/common/block-range-scanner/block-range-scan.mongo.source.ts rename to src/reader/block-range-scanner/block-range-scan.mongo.source.ts index 2c3fb38..027aeb2 100644 --- a/src/common/block-range-scanner/block-range-scan.mongo.source.ts +++ b/src/reader/block-range-scanner/block-range-scan.mongo.source.ts @@ -195,7 +195,5 @@ export class BlockRangeScanMongoSource extends CollectionMongoSource { + let mongoSource: MongoSource; + + log(` * Block Range Scanner ... [starting]`); + + if (mongo instanceof MongoSource) { + mongoSource = mongo; + } else { + mongoSource = await MongoSource.create(mongo); + } + const source = new BlockRangeScanMongoSource(mongoSource); + const repository = new BlockRangeScanRepository(source, config); + const scanner: BlockRangeScanner = new BlockRangeScanner(repository); + + log(` * Block Range Scanner ... [ready]`); + return scanner; + } + constructor(private blockRangeScanRepository: BlockRangeScanRepository) {} public async createScanNodes( @@ -38,10 +62,7 @@ export class BlockRangeScanner { return this.blockRangeScanRepository.hasUnscannedNodes(key, startBlock, endBlock); } - public async updateScanProgress( - scanKey: string, - blockNumber: bigint - ): Promise { + public async updateScanProgress(scanKey: string, blockNumber: bigint): Promise { await this.blockRangeScanRepository.updateScannedBlockNumber(scanKey, blockNumber); } } diff --git a/src/common/block-range-scanner/index.ts b/src/reader/block-range-scanner/index.ts similarity index 87% rename from src/common/block-range-scanner/index.ts rename to src/reader/block-range-scanner/index.ts index 6287a62..6432c68 100644 --- a/src/common/block-range-scanner/index.ts +++ b/src/reader/block-range-scanner/index.ts @@ -5,4 +5,3 @@ export * from './block-range-scanner.config'; export * from './block-range-scanner.dtos'; export * from './block-range-scanner.errors'; export * from './block-range-scanner'; -export * from './block-range-scanner.utils'; diff --git a/src/reader/index.ts b/src/reader/index.ts new file mode 100644 index 0000000..efc844c --- /dev/null +++ b/src/reader/index.ts @@ -0,0 +1,7 @@ +export * from '../common/blockchain/block-reader'; +export * from './unprocessed-block-queue'; +export * from './reader.types'; +export * from './reader'; +export * from './reader.worker-loader'; +export * from './reader.worker'; +export * from './start-reader'; diff --git a/src/reader/reader.ts b/src/reader/reader.ts new file mode 100644 index 0000000..2d53d8f --- /dev/null +++ b/src/reader/reader.ts @@ -0,0 +1,126 @@ +import { Broadcast, BroadcastClient, log, MongoSource } from '@alien-worlds/api-core'; +import { BlockRangeScanner } from './block-range-scanner'; +import { Mode } from '../common/common.enums'; +import { WorkerMessage, WorkerPool } from '../common/workers'; +import ReaderWorker from './reader.worker'; +import { ReadCompleteData, ReaderConfig, ReadTaskData } from './reader.types'; +import { InternalBroadcastClientName } from '../broadcast'; +import { FilterBroadcastMessage } from '../broadcast/messages'; + +export class Reader { + public static async create( + config: ReaderConfig, + broadcastClient?: BroadcastClient + ): Promise { + const mongoSource = await MongoSource.create(config.mongo); + const scanner = await BlockRangeScanner.create(mongoSource, config.scanner); + const workerPool = await WorkerPool.create({ + threadsCount: config.workers?.threadsCount || 1, + sharedData: { config }, + defaultWorkerPath: `${__dirname}/reader.worker`, + workerLoaderPath: `${__dirname}/reader.worker-loader`, + }); + let broadcast: BroadcastClient; + if (!broadcastClient) { + broadcast = await Broadcast.createClient({ + ...config.broadcast, + clientName: InternalBroadcastClientName.Reader, + }); + broadcast.connect(); + } else { + broadcast = broadcastClient; + } + return new Reader(workerPool, scanner, broadcast); + } + + private loop = false; + private isAlreadyStarted = false; + private initTaskData: ReadTaskData; + + protected constructor( + private workerPool: WorkerPool, + private scanner: BlockRangeScanner, + private broadcast: BroadcastClient + ) { + workerPool.onWorkerRelease(async () => { + const { initTaskData } = this; + if (initTaskData.mode === Mode.Replay) { + if (await this.scanner.hasUnscannedBlocks(initTaskData.scanKey)) { + this.read(initTaskData); + } + } else { + // + } + }); + } + + private async handleWorkerMessage(message: WorkerMessage) { + const { workerPool, broadcast } = this; + const { data, error, workerId } = message; + + if (message.isTaskResolved()) { + const { startBlock, endBlock } = data; + log( + `All blocks in the range ${startBlock.toString()} - ${endBlock.toString()} (exclusive) have been read.` + ); + workerPool.releaseWorker(workerId, data); + } else if (message.isTaskRejected()) { + log(`An unexpected error occurred while reading blocks...`, error); + workerPool.releaseWorker(workerId); + } else if (message.isTaskProgress()) { + broadcast.sendMessage(FilterBroadcastMessage.refresh()); + } + } + + private async handleWorkerError(id: number, error: Error) { + log(`Worker error:`, error); + this.workerPool.releaseWorker(id); + } + + public async read(task: ReadTaskData) { + if (this.loop) { + return; + } + this.loop = true; + + if (!this.initTaskData) { + this.initTaskData = task; + log( + `Preparation for scanning block range (${task.startBlock}-${task.endBlock}) ${ + task.mode === Mode.Replay ? 'under the label ' + task.scanKey : '' + }` + ); + } + + while (this.loop) { + const { initTaskData, workerPool } = this; + const worker = await workerPool.getWorker(); + if (worker) { + worker.onMessage(message => this.handleWorkerMessage(message)); + worker.onError((id, error) => this.handleWorkerError(id, error)); + + if (task.mode === Mode.Default || task.mode === Mode.Test) { + worker.run({ startBlock: task.startBlock, endBlock: task.endBlock }); + } else if (task.mode === Mode.Replay) { + const scan = await this.scanner.getNextScanNode(task.scanKey); + + if (scan) { + worker.run({ + startBlock: scan.start, + endBlock: scan.end, + scanKey: initTaskData.scanKey, + }); + } else { + log( + `The scan of the range ${initTaskData.startBlock}-${initTaskData.endBlock}(exclusive) under the label "${initTaskData.scanKey}" has already been completed. No subranges to process.` + ); + workerPool.releaseWorker(worker.id); + this.loop = false; + } + } + } else { + this.loop = false; + } + } + } +} diff --git a/src/reader/reader.types.ts b/src/reader/reader.types.ts new file mode 100644 index 0000000..2d97aae --- /dev/null +++ b/src/reader/reader.types.ts @@ -0,0 +1,45 @@ +import { BroadcastConfig, MongoConfig } from '@alien-worlds/api-core'; +import { BlockRangeScanConfig } from './block-range-scanner'; +import { WorkersConfig } from '../common/workers'; +import { BlockReaderConfig } from '../common/blockchain/block-reader'; + +export type ReaderConfig = { + broadcast?: BroadcastConfig; + blockReader?: BlockReaderConfig; + mongo?: MongoConfig; + scanner?: BlockRangeScanConfig; + workers?: WorkersConfig; + mode?: string; + maxBlockNumber?: number; + blockQueueMaxBytesSize?: number; + blockQueueSizeCheckInterval?: number; + blockQueueBatchSize?: number; + startBlock?: bigint; + endBlock?: bigint; +}; + +export type ReaderCommandOptions = { + startBlock?: bigint; + endBlock?: bigint; + mode?: string; + scanKey?: string; + threads?: number; +}; + +export type ReadTaskData = { + startBlock?: bigint; + endBlock?: bigint; + mode?: string; + scanKey?: string; +}; + +export type ReadCompleteData = { + startBlock?: bigint; + endBlock?: bigint; + scanKey?: string; +}; + +export type ReadProgressData = { + min?: bigint; + max?: bigint; +}; diff --git a/src/reader/reader.worker-loader.ts b/src/reader/reader.worker-loader.ts new file mode 100644 index 0000000..e20d8dc --- /dev/null +++ b/src/reader/reader.worker-loader.ts @@ -0,0 +1,71 @@ +import { MongoSource, log } from '@alien-worlds/api-core'; +import { BlockReader } from '../common/blockchain'; +import { Worker } from '../common/workers'; +import { DefaultWorkerLoader } from '../common/workers/worker-loader'; +import { UnprocessedBlockQueue } from './unprocessed-block-queue'; +import ReaderWorker, { ReaderSharedData } from './reader.worker'; +import { BlockRangeScanner, BlockState } from '../common'; + +export default class ReaderWorkerLoader extends DefaultWorkerLoader { + private blockReader: BlockReader; + private blockState: BlockState; + private blocksQueue: UnprocessedBlockQueue; + private scanner: BlockRangeScanner; + + public async setup(sharedData: ReaderSharedData): Promise { + super.setup(sharedData); + + const { + config: { + blockReader, + mongo, + blockQueueBatchSize, + blockQueueMaxBytesSize, + blockQueueSizeCheckInterval, + scanner, + }, + } = sharedData; + const mongoSource = await MongoSource.create(mongo); + this.blockReader = await BlockReader.create(blockReader); + this.blockState = await BlockState.create(mongoSource); + this.scanner = await BlockRangeScanner.create(mongoSource, scanner); + this.blocksQueue = await UnprocessedBlockQueue.create( + mongoSource, + blockQueueMaxBytesSize, + blockQueueBatchSize + ); + this.blocksQueue.onOverload(size => { + const overload = size - blockQueueMaxBytesSize; + log(`Overload: ${overload} bytes.`); + this.blockReader.pause(); + + let interval = setInterval(async () => { + const { content: size, failure } = await this.blocksQueue.getBytesSize(); + + if (failure) { + log( + `Failed to get unprocessed blocks collection size: ${failure.error.message}` + ); + } else if (size === 0) { + log(`Unprocessed blocks collection cleared, blockchain reading resumed.`); + this.blockReader.resume(); + clearInterval(interval); + interval = null; + } + }, blockQueueSizeCheckInterval || 1000); + }); + this.blocksQueue.beforeSendBatch(() => { + this.blockReader.pause(); + }); + this.blocksQueue.afterSendBatch(() => { + this.blockReader.resume(); + }); + + await this.blockReader.connect(); + } + + public async load(): Promise { + const { blockReader, scanner, blocksQueue, blockState, sharedData } = this; + return new ReaderWorker(blockReader, blocksQueue, blockState, scanner, sharedData); + } +} diff --git a/src/reader/reader.worker.ts b/src/reader/reader.worker.ts new file mode 100644 index 0000000..8f2f289 --- /dev/null +++ b/src/reader/reader.worker.ts @@ -0,0 +1,176 @@ +import { log, parseToBigInt } from '@alien-worlds/api-core'; +import { Worker } from '../common/workers/worker'; +import { BlockReader } from '../common/blockchain/block-reader'; +import { ReaderConfig } from './reader.types'; +import { UnprocessedBlockQueue } from './unprocessed-block-queue'; +import { BlockRangeScanner, BlockState, Mode } from '../common'; + +export type ReaderSharedData = { + config: ReaderConfig; +}; + +export default class ReaderWorker extends Worker { + constructor( + protected blockReader: BlockReader, + protected blockQueue: UnprocessedBlockQueue, + protected blockState: BlockState, + protected scanner: BlockRangeScanner, + sharedData: ReaderSharedData + ) { + super(); + this.sharedData = sharedData; + } + + private async updateBlockState(): Promise { + const { blockQueue, blockState } = this; + const { content: maxBlock } = await blockQueue.getMax(); + if (maxBlock) { + const { failure } = await blockState.updateBlockNumber( + maxBlock.thisBlock.blockNumber + ); + if (failure) { + log('Something went wrong, the block state was not updated.'); + } + } else { + log( + 'Something went wrong, the block with the highest number was not found/received.' + ); + } + } + + private logProgress(blockNumbers: bigint[]) { + const sorted = blockNumbers.sort(); + const min = sorted[0]; + const max = sorted.reverse()[0]; + + log(`Blocks ${min.toString()}-${max.toString()} have been read.`); + } + + private async readInDefaultMode(startBlock: bigint, endBlock: bigint) { + const { + blockReader, + blockQueue, + sharedData: { + config: { + maxBlockNumber, + blockReader: { shouldFetchDeltas, shouldFetchTraces, shouldFetchBlock }, + blockQueueMaxBytesSize, + }, + }, + } = this; + + blockReader.onReceivedBlock(async block => { + const isLast = endBlock === block.thisBlock.blockNumber; + const { content: addedBlockNumbers, failure } = await blockQueue.add(block, isLast); + + if (Array.isArray(addedBlockNumbers) && addedBlockNumbers.length > 0) { + this.logProgress(addedBlockNumbers); + + await this.updateBlockState(); + this.progress(); + // + } else if (failure?.error.name === 'DuplicateBlocksError') { + log(failure.error.message); + } else if (failure?.error.name === 'UnprocessedBlocksOverloadError') { + log(failure.error.message); + log( + `The size limit ${blockQueueMaxBytesSize} of the unprocessed blocks collection has been exceeded. Blockchain reading suspended until the collection is cleared.` + ); + } else if (failure) { + this.reject(failure.error); + } else { + // + } + }); + + blockReader.onError(error => { + this.reject(error); + }); + + blockReader.onComplete(async () => { + this.resolve({ startBlock, endBlock }); + }); + + blockReader.readBlocks( + startBlock, + endBlock || parseToBigInt(maxBlockNumber || 0xffffffff), + { + shouldFetchBlock, + shouldFetchDeltas, + shouldFetchTraces, + } + ); + } + + private async readInReplayMode(startBlock: bigint, endBlock: bigint, scanKey: string) { + const { + blockReader, + blockQueue, + scanner, + sharedData: { + config: { + blockReader: { shouldFetchDeltas, shouldFetchTraces, shouldFetchBlock }, + blockQueueMaxBytesSize, + }, + }, + } = this; + + blockReader.onReceivedBlock(async block => { + const { content: addedBlockNumbers, failure } = await blockQueue.add(block); + if (Array.isArray(addedBlockNumbers) && addedBlockNumbers.length > 0) { + this.logProgress(addedBlockNumbers); + + for (const blockNumber of addedBlockNumbers) { + await scanner.updateScanProgress(scanKey, blockNumber); + } + + this.progress({ startBlock, endBlock, scanKey }); + // + } else if (failure?.error.name === 'DuplicateBlocksError') { + log(failure.error.message); + } else if (failure?.error.name === 'UnprocessedBlocksOverloadError') { + log(failure.error.message); + log( + `The size limit ${blockQueueMaxBytesSize} of the unprocessed blocks collection has been exceeded by bytes. Blockchain reading suspended until the collection is cleared.` + ); + } else if (failure) { + this.reject(failure.error); + } + }); + + blockReader.onError(error => { + this.reject(error); + }); + + blockReader.onComplete(async () => { + this.resolve({ startBlock, endBlock, scanKey }); + }); + + blockReader.readBlocks(startBlock, endBlock, { + shouldFetchBlock, + shouldFetchDeltas, + shouldFetchTraces, + }); + } + + public async run(args: { + startBlock: bigint; + endBlock: bigint; + scanKey: string; + }): Promise { + const { startBlock, endBlock, scanKey } = args; + const { + sharedData: { + config: { mode }, + }, + } = this; + + if (mode === Mode.Replay) { + this.readInReplayMode(startBlock, endBlock, scanKey); + } else if (mode === Mode.Default || mode === Mode.Test) { + this.readInDefaultMode(startBlock, endBlock); + } else { + log(`Unknown mode ${mode}`); + } + } +} diff --git a/src/reader/start-reader.ts b/src/reader/start-reader.ts new file mode 100644 index 0000000..36272f8 --- /dev/null +++ b/src/reader/start-reader.ts @@ -0,0 +1,55 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { + InternalBroadcastChannel, + InternalBroadcastClientName, + InternalBroadcastMessageName, +} from '../broadcast/internal-broadcast.enums'; +import { Broadcast, log } from '@alien-worlds/api-core'; +import { ReadTaskData, ReaderConfig } from './reader.types'; +import { InternalBroadcastMessage } from '../broadcast/internal-broadcast.message'; +import { ReaderBroadcastMessage } from '../broadcast/messages/reader-broadcast.message'; +import { Reader } from './reader'; +import { Mode } from '../common'; + +/** + * + * @param config + * @returns + */ +export const startReader = async (config: ReaderConfig) => { + log(`Reader ... [starting]`); + const broadcast = await Broadcast.createClient({ + ...config.broadcast, + clientName: InternalBroadcastClientName.Reader, + }); + const blockRangeReader = await Reader.create(config, broadcast); + let channel: string; + let readyMessage; + + if (config.mode === Mode.Replay) { + channel = InternalBroadcastChannel.ReplayModeReader; + readyMessage = ReaderBroadcastMessage.replayModeReady(); + } else { + channel = InternalBroadcastChannel.DefaultModeReader; + readyMessage = ReaderBroadcastMessage.defaultModeReady(); + } + + log(`Reader started in "listening" mode`); + broadcast.onMessage( + channel, + async (message: InternalBroadcastMessage) => { + const { + content: { data, name }, + } = message; + if (name === InternalBroadcastMessageName.ReaderTask) { + blockRangeReader.read(data); + } + } + ); + broadcast.connect(); + // Everything is ready, notify the bootstrap that the process is ready to work + broadcast.sendMessage(readyMessage); + + log(`Reader ... [ready]`); +}; diff --git a/src/reader/unprocessed-block-queue/index.ts b/src/reader/unprocessed-block-queue/index.ts new file mode 100644 index 0000000..afcb8e8 --- /dev/null +++ b/src/reader/unprocessed-block-queue/index.ts @@ -0,0 +1,2 @@ +export * from './unprocessed-block-queue.errors'; +export * from './unprocessed-block-queue'; diff --git a/src/reader/unprocessed-block-queue/unprocessed-block-queue.errors.ts b/src/reader/unprocessed-block-queue/unprocessed-block-queue.errors.ts new file mode 100644 index 0000000..09d8512 --- /dev/null +++ b/src/reader/unprocessed-block-queue/unprocessed-block-queue.errors.ts @@ -0,0 +1,14 @@ +export class BlockNotFoundError extends Error {} +export class DuplicateBlocksError extends Error { + constructor() { + super(`Some blocks in the specified range are already in the database.`); + this.name = 'DuplicateBlocksError'; + } +} + +export class UnprocessedBlocksOverloadError extends Error { + constructor(min: bigint, max: bigint) { + super(`Blocks ${min}-${max} were read before the overload occurred.`); + this.name = 'UnprocessedBlocksOverloadError'; + } +} diff --git a/src/reader/unprocessed-block-queue/unprocessed-block-queue.ts b/src/reader/unprocessed-block-queue/unprocessed-block-queue.ts new file mode 100644 index 0000000..8c7aec2 --- /dev/null +++ b/src/reader/unprocessed-block-queue/unprocessed-block-queue.ts @@ -0,0 +1,194 @@ +import { + CollectionMongoSource, + DataSourceBulkWriteError, + DataSourceOperationError, + Failure, + isMongoConfig, + log, + MongoConfig, + MongoSource, + parseToBigInt, + Result, +} from '@alien-worlds/api-core'; +import { + BlockNotFoundError, + DuplicateBlocksError, + UnprocessedBlocksOverloadError, +} from './unprocessed-block-queue.errors'; +import { Block, BlockDocument } from '../../common/blockchain/block-reader/block'; + +export class BlockMongoCollection extends CollectionMongoSource { + constructor(mongoSource: MongoSource) { + super(mongoSource, 'history_tools.unprocessed_blocks', { + indexes: [ + { + key: { 'this_block.block_num': 1 }, + unique: true, + background: true, + }, + ], + }); + } + + public async next(): Promise { + try { + const result = await this.collection.findOneAndDelete({}); + return result.value; + } catch (error) { + throw DataSourceOperationError.fromError(error); + } + } + + public async bytesSize(): Promise { + const stats = await this.collection.stats(); + return stats.size; + } +} + +export abstract class UnprocessedBlockQueueReader { + public abstract next(): Promise>; +} + +export class UnprocessedBlockQueue implements UnprocessedBlockQueueReader { + private cache: Block[]; + private mongo: BlockMongoCollection; + private overloadHandler: (size: number) => void; + private beforeSendBatchHandler: () => void; + private afterSendBatchHandler: () => void; + + public static async create< + T extends UnprocessedBlockQueue | UnprocessedBlockQueueReader + >( + mongo: MongoConfig | MongoSource, + maxBytesSize?: number, + batchSize?: number + ): Promise { + let mongoSource: MongoSource; + if (isMongoConfig(mongo)) { + mongoSource = await MongoSource.create(mongo); + } else { + mongoSource = mongo; + } + return new UnprocessedBlockQueue( + mongoSource, + maxBytesSize || 0, + batchSize | 100 + ) as T; + } + + private constructor( + mongoSource: MongoSource, + private maxBytesSize: number, + private batchSize: number + ) { + this.mongo = new BlockMongoCollection(mongoSource); + this.cache = []; + } + + private async sendBatch() { + const addedBlockNumbers = []; + this.beforeSendBatchHandler(); + const documnets = this.cache.map(block => block.toDocument()); + const result = await this.mongo.insertMany(documnets); + result.forEach(document => { + addedBlockNumbers.push(parseToBigInt(document.this_block.block_num)); + }); + this.cache = []; + + if (this.maxBytesSize > 0 && this.overloadHandler) { + const sorted = addedBlockNumbers.sort(); + const min = sorted[0]; + const max = sorted.reverse()[0]; + + const currentSize = await this.mongo.bytesSize(); + if (currentSize >= this.maxBytesSize) { + this.overloadHandler(currentSize); + throw new UnprocessedBlocksOverloadError(min, max); + } + } + + this.afterSendBatchHandler(); + + return addedBlockNumbers; + } + + public async getBytesSize(): Promise> { + try { + const currentSize = await this.mongo.bytesSize(); + return Result.withContent(currentSize); + } catch (error) { + return Result.withFailure(Failure.fromError(error)); + } + } + + public async add(block: Block, isLast = false): Promise> { + try { + let addedBlockNumbers: bigint[] = []; + + if (this.cache.length < this.batchSize) { + this.cache.push(block); + } + + if (this.cache.length === this.batchSize || isLast) { + addedBlockNumbers = await this.sendBatch(); + } + + return Result.withContent(addedBlockNumbers); + } catch (error) { + // it is important to clear the cache in case of errors + this.cache = []; + + if (error instanceof DataSourceBulkWriteError && error.onlyDuplicateErrors) { + this.afterSendBatchHandler(); + return Result.withFailure(Failure.fromError(new DuplicateBlocksError())); + } + return Result.withFailure(Failure.fromError(error)); + } + } + + public async next(): Promise> { + try { + const document = await this.mongo.next(); + if (document) { + if (this.maxBytesSize > -1 && this.afterSendBatchHandler) { + if ((await this.mongo.count({})) === 0 && this.afterSendBatchHandler) { + this.afterSendBatchHandler(); + } + } + + return Result.withContent(Block.fromDocument(document)); + } + return Result.withFailure(Failure.fromError(new BlockNotFoundError())); + } catch (error) { + log(`Could not get next task due to: ${error.message}`); + return Result.withFailure(Failure.fromError(error)); + } + } + + public async getMax(): Promise> { + try { + const documents = await this.mongo.aggregate({ + pipeline: [{ $sort: { 'this_block.block_num': -1 } }, { $limit: 1 }], + }); + if (documents.length > 0) { + return Result.withContent(Block.fromDocument(documents[0])); + } + return Result.withFailure(Failure.fromError(new BlockNotFoundError())); + } catch (error) { + log(`Could not get block with highest block number due to: ${error.message}`); + return Result.withFailure(Failure.fromError(error)); + } + } + + public afterSendBatch(handler: () => void): void { + this.afterSendBatchHandler = handler; + } + + public beforeSendBatch(handler: () => void): void { + this.beforeSendBatchHandler = handler; + } + + public onOverload(handler: (size: number) => void): void { + this.overloadHandler = handler; + } +} diff --git a/yarn.lock b/yarn.lock index adb79b2..cb8112f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11,10 +11,10 @@ debug "^4.3.4" safe-buffer "~5.1.2" -"@alien-worlds/api-core@^0.0.87": - version "0.0.87" - resolved "https://npm.pkg.github.com/download/@alien-worlds/api-core/0.0.87/f25d104f3974cf7e0c3a514d2d8c50b147b65900#f25d104f3974cf7e0c3a514d2d8c50b147b65900" - integrity sha512-g8jKkq4tI7NQDHEwvZmFcQAHmaNmho2DtnmrFIG+Vqd42LWnSvYByt2fry/bkAqRu61jSIa19wAXjGXKceFI+A== +"@alien-worlds/api-core@^0.0.101": + version "0.0.101" + resolved "https://npm.pkg.github.com/download/@alien-worlds/api-core/0.0.101/c67f2c0741a464be6d0391b98691ca9c2ac74eb9#c67f2c0741a464be6d0391b98691ca9c2ac74eb9" + integrity sha512-9hgizhXjYL+PsxsYnrwwL3KRHVvuiVaPjovM2w6U06PTbLXYDkalHQ+em15OQ29DkOd8WGoM1cWW+LTLx6Ec+w== dependencies: "@google-cloud/bigquery" "^6.0.3" amqplib "^0.10.3"