From 628de71ca8ce5b4079b6bc471180282db9e4e1d9 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Sat, 6 Nov 2021 14:01:13 +0530 Subject: [PATCH] Adopt BaseTcpServerHandler within HttpProtocolHandler (#681) * Rename .server to .upstream * Lint fixes * Mark internal methods with _ prefix * Fix broken test * lint changes * Wah, double client :D * Avoid selector initialization for threadless mode * remove unused imports * Now HttpProtocolHandler implements BaseTcpServerHandler * Consistent return and guard againt upstream.closed * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * AcceptorPool as context manager * Group multiprocessing imports together * Use com.jaxl bundle identifier as proxy.py will eventually move under jaxl org * revisit devtools integration :) * Emit all necessary events for devtools integration * Lint fixes Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- Makefile | 2 +- dashboard/package-lock.json | 5304 ++++++++++++++++- dashboard/src/core/devtools.ts | 22 +- .../src/core/plugins/inspect_traffic.html | 13 +- dashboard/src/core/plugins/inspect_traffic.js | 5 +- .../src/core/plugins/inspect_traffic.json | 32 +- dashboard/src/manifest.json | 64 +- examples/https_connect_tunnel.py | 22 +- examples/ssl_echo_server.py | 17 +- examples/tcp_echo_server.py | 17 +- helper/chrome_with_rdp.sh | 18 + menubar/proxy.py.xcodeproj/project.pbxproj | 4 +- .../UserInterfaceState.xcuserstate | Bin 26859 -> 22357 bytes menubar/proxy.py/Info.plist | 6 +- proxy/common/constants.py | 7 +- proxy/core/acceptor/pool.py | 14 + proxy/core/acceptor/threadless.py | 2 +- proxy/core/base/tcp_server.py | 122 +- proxy/core/base/tcp_tunnel.py | 10 +- proxy/http/handler.py | 360 +- proxy/http/inspector/devtools.py | 8 +- proxy/http/inspector/transformer.py | 154 +- proxy/http/proxy/server.py | 129 +- .../exceptions/test_http_proxy_auth_failed.py | 8 +- tests/http/test_http_proxy.py | 4 +- .../http/test_http_proxy_tls_interception.py | 2 +- tests/http/test_protocol_handler.py | 29 +- tests/http/test_web_server.py | 16 +- tests/plugin/test_http_proxy_plugins.py | 16 +- ...ttp_proxy_plugins_with_tls_interception.py | 10 +- 30 files changed, 5928 insertions(+), 489 deletions(-) create mode 100755 helper/chrome_with_rdp.sh diff --git a/Makefile b/Makefile index d4f0e6d316..bb404d70d5 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ lib-release: lib-package twine upload dist/* lib-coverage: - pytest --cov=proxy --cov-report=html tests/ + pytest --cov=proxy --cov=tests --cov-report=html tests/ open htmlcov/index.html lib-profile: diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 33a6d32b76..476e3fb45d 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -1,8 +1,5295 @@ { "name": "proxy.py", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "proxy.py", + "version": "1.0.0", + "license": "BSD-3-Clause", + "devDependencies": { + "@types/jasmine": "^3.6.1", + "@types/jquery": "^3.5.4", + "@types/js-cookie": "^2.2.6", + "@typescript-eslint/eslint-plugin": "^2.34.0", + "@typescript-eslint/parser": "^2.34.0", + "chrome-devtools-frontend": "^1.0.827632", + "eslint": "^6.8.0", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^10.0.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.1.0", + "http-server": "^0.12.3", + "jasmine": "^3.6.3", + "jasmine-ts": "^0.3.0", + "jquery": "^3.5.1", + "js-cookie": "^2.2.1", + "jsdom": "^15.2.1", + "ncp": "^2.0.0", + "rollup": "^1.32.1", + "rollup-plugin-copy": "^3.3.0", + "rollup-plugin-javascript-obfuscator": "^1.0.4", + "rollup-plugin-typescript": "^1.0.1", + "ts-node": "^7.0.1", + "typescript": "^3.9.7", + "ws": "^7.4.6" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.scandir/node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "node_modules/@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", + "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.1.tgz", + "integrity": "sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.1.tgz", + "integrity": "sha512-eeSCVhBsgwHNS1FmaMu4zrLxfykCTWJMLFZv7lmyrZQjw7foUUXoPu4GukSN9v7JvUw7X+/aDH3kCaymirBSTg==", + "dev": true + }, + "node_modules/@types/jquery": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.4.tgz", + "integrity": "sha512-//9CHhaUt/rurMJTxGI+I6DmsNHgYU6d8aSLFfO5dB7+10lwLnaWT0z5GY/yY82Q/M+B+0Qh3TixlJ8vmBeqIw==", + "dev": true, + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/js-cookie": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.6.tgz", + "integrity": "sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "node_modules/@types/validator": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-10.11.3.tgz", + "integrity": "sha512-GKF2VnEkMmEeEGvoo03ocrP9ySMuX1ypKazIYMlsjfslfBMhOAtC5dmEWKdJioW4lJN7MZRS88kalTsVClyQ9w==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^2.0.0", + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "dev": true, + "dependencies": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/abab": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", + "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "node_modules/babel-polyfill": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", + "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "core-js": "^2.4.0", + "regenerator-runtime": "^0.10.0" + } + }, + "node_modules/babel-polyfill/node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/basic-auth": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/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 + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chrome-devtools-frontend": { + "version": "1.0.827632", + "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.827632.tgz", + "integrity": "sha512-8qtv6zxlaoZhmtPFrR/dAyXjCKCSXL8s7SeAaHyICpd7p6mfXS+y+b14E66LLbOIEMwpidmy3xUJPePx8NuWHg==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", + "deprecated": "core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true, + "engines": { + "node": "*" + } + }, + "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 + }, + "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, + "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 + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecstatic": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", + "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", + "deprecated": "This package is unmaintained and deprecated. See the GH Issue 259.", + "dev": true, + "dependencies": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "bin": { + "ecstatic": "lib/ecstatic.js" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "dependencies": { + "iconv-lite": "~0.4.13" + } + }, + "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, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true, + "peerDependencies": { + "eslint": ">=6.2.2", + "eslint-plugin-import": ">=2.18.0", + "eslint-plugin-node": ">=9.1.0", + "eslint-plugin-promise": ">=4.2.1", + "eslint-plugin-standard": ">=4.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-es": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", + "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^1.4.2", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-import/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-node": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz", + "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^2.0.0", + "eslint-utils": "^1.4.2", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "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" + } + ], + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "dependencies": { + "type-fest": "^0.11.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/eslint/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/eslint/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint/node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint/node_modules/inquirer/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/eslint/node_modules/onetime": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.1.tgz", + "integrity": "sha512-ZpZpjcJeugQfWsfyQlshVoowIIQ1qBGSVll4rfDq6JJVO//fesjoX808hXWfBjY+ROZgpKDI5TRSRBSoJiZ8eg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/eslint/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", + "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", + "dev": true, + "dependencies": { + "debug": "^3.0.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/globby/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/globby/node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/google-libphonenumber": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-3.2.5.tgz", + "integrity": "sha512-Y0r7MFCI11UDLn0KaMPBEInhROyIOkWkQIyvWMFVF2I+h+sHE3vbl5a7FVe39td6u/w+nlKDdUMP9dMOZyv+2Q==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", + "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", + "dev": true, + "dependencies": { + "basic-auth": "^1.0.3", + "colors": "^1.4.0", + "corser": "^2.0.1", + "ecstatic": "^3.3.2", + "http-proxy": "^1.18.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.25", + "secure-compare": "3.0.1", + "union": "~0.5.0" + }, + "bin": { + "hs": "bin/http-server", + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inquirer": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", + "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.1.0", + "chalk": "^1.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.1", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx": "^4.1.0", + "string-width": "^2.0.0", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/jasmine": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz", + "integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "jasmine-core": "~3.6.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + }, + "engines": { + "node": "^10 || ^12 || ^14" + } + }, + "node_modules/jasmine-core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz", + "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==", + "dev": true + }, + "node_modules/jasmine-ts": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/jasmine-ts/-/jasmine-ts-0.3.0.tgz", + "integrity": "sha512-K5joodjVOh3bnD06CNXC8P5htDq/r0Rhjv66ECOpdIGFLly8kM7V+X/GXcd9kv+xO+tIq3q9Y8B5OF6yr/iiDw==", + "dev": true, + "dependencies": { + "yargs": "^8.0.2" + }, + "bin": { + "jasmine-ts": "lib/index.js" + }, + "engines": { + "node": ">= 5.12" + }, + "peerDependencies": { + "jasmine": ">= 2.0", + "ts-node": ">=3.2.0 <8", + "typescript": ">=2.4.1" + } + }, + "node_modules/javascript-obfuscator": { + "version": "0.18.8", + "resolved": "https://registry.npmjs.org/javascript-obfuscator/-/javascript-obfuscator-0.18.8.tgz", + "integrity": "sha512-lh/PT3dwLgv2vP9ymsmNZqjpbkDq1SQqpxLYtAerLzmYgHlQOzVpUe3NbFb8tUFNylMeg6ez1iEpA7oOQw/7Tw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@babel/runtime": "7.7.4", + "chalk": "3.0.0", + "chance": "1.1.3", + "class-validator": "0.11.0", + "commander": "4.0.1", + "escodegen-wallaby": "1.6.27", + "espree": "^6.1.2", + "estraverse": "4.3.0", + "eventemitter3": "4.0.0", + "inversify": "5.0.1", + "js-string-escape": "1.0.1", + "md5": "2.2.1", + "mkdirp": "0.5.1", + "multimatch": "4.0.0", + "opencollective": "1.0.3", + "reflect-metadata": "0.1.13", + "source-map-support": "0.5.16", + "string-template": "1.0.0", + "tslib": "1.10.0" + }, + "bin": { + "javascript-obfuscator": "bin/javascript-obfuscator" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/@babel/runtime": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", + "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.2" + } + }, + "node_modules/javascript-obfuscator/node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/javascript-obfuscator/node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/chance": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.3.tgz", + "integrity": "sha512-XeJsdoVAzDb1WRPRuMBesRSiWpW1uNTo5Fd7mYxPJsAfgX71+jfuCOHOdbyBz2uAUZ8TwKcXgWk3DMedFfJkbg==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/class-validator": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.11.0.tgz", + "integrity": "sha512-niAmmSPFku9xsnpYYrddy8NZRrCX3yyoZ/rgPKOilE5BG0Ma1eVCIxpR4X0LasL/6BzbYzsutG+mSbAXlh4zNw==", + "dev": true, + "dependencies": { + "@types/validator": "10.11.3", + "google-libphonenumber": "^3.1.6", + "validator": "12.0.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/commander": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.0.1.tgz", + "integrity": "sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/javascript-obfuscator/node_modules/escodegen-wallaby": { + "version": "1.6.27", + "resolved": "https://registry.npmjs.org/escodegen-wallaby/-/escodegen-wallaby-1.6.27.tgz", + "integrity": "sha512-DFXbfLTNa/wiQRgqSseKhmzyDhwWJ4c/6IwsdAgA6qYL0ntsmSuuTMovEbA/8oCanSGkUR1qaLsDgKiWPllnjg==", + "dev": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.10.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/escodegen-wallaby/node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/inversify": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.1.tgz", + "integrity": "sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/javascript-obfuscator/node_modules/multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/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==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-obfuscator/node_modules/tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "node_modules/javascript-obfuscator/node_modules/validator": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-12.0.0.tgz", + "integrity": "sha512-r5zA1cQBEOgYlesRmSEwc9LkbfNLTtji+vWyaHzRZUxCTHdsX3bd+sdHfs5tGZ2W6ILGGsxWxCNwT/h3IY/3ng==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/jquery": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", + "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==", + "dev": true + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "dev": true + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "node_modules/md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "dependencies": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "node_modules/mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "dev": true, + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", + "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", + "dev": true, + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", + "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=", + "dev": true, + "dependencies": { + "babel-polyfill": "6.23.0", + "chalk": "1.1.3", + "inquirer": "3.0.6", + "minimist": "1.2.0", + "node-fetch": "1.6.3", + "opn": "4.0.2" + }, + "bin": { + "oc": "dist/bin/opencollective.js", + "opencollective": "dist/bin/opencollective.js" + } + }, + "node_modules/opencollective/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/opencollective/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/opn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "dependencies": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "node_modules/portfinder": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", + "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/node": "*", + "acorn": "^7.1.0" + }, + "bin": { + "rollup": "dist/bin/rollup" + } + }, + "node_modules/rollup-plugin-copy": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.3.0.tgz", + "integrity": "sha512-euDjCUSBXZa06nqnwCNADbkAcYDfzwowfZQkto9K/TFhiH+QG7I4PUsEMwM9tDgomGWJc//z7KLW8t+tZwxADA==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^8.0.1", + "colorette": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "10.0.1", + "is-plain-object": "^3.0.0" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/rollup-plugin-copy/node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup-plugin-javascript-obfuscator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/rollup-plugin-javascript-obfuscator/-/rollup-plugin-javascript-obfuscator-1.0.4.tgz", + "integrity": "sha512-pFn5NTqbjWDNMW2WIW9x+GecouGN5Y6fd6oOPLtLwbb0VlBoAiflrbW7WqK1k19ptEIAf5IfAYv0GNIVefhw/A==", + "dev": true, + "dependencies": { + "javascript-obfuscator": "^0.18.1" + } + }, + "node_modules/rollup-plugin-typescript": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-1.0.1.tgz", + "integrity": "sha512-rwJDNn9jv/NsKZuyBb/h0jsclP4CJ58qbvZt2Q9zDIGILF2LtdtvCqMOL+Gq9IVq5MTrTlHZNrn8h7VjQgd8tw==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-typescript.", + "dev": true, + "dependencies": { + "resolve": "^1.10.0", + "rollup-pluginutils": "^2.5.0" + }, + "peerDependencies": { + "tslib": "*", + "typescript": ">=2.1.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "dependencies": { + "xmlchars": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "dev": true + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=", + "dev": true + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend/node_modules/es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart/node_modules/es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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 + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/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, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "dependencies": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "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, + "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 + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "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/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 + }, + "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 + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "node_modules/yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true, + "engines": { + "node": ">=4" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", @@ -265,7 +5552,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "6.2.0", @@ -1236,7 +6524,8 @@ "version": "14.1.1", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", - "dev": true + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.4", @@ -1410,7 +6699,8 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", - "dev": true + "dev": true, + "requires": {} }, "eslint-scope": { "version": "5.1.0", @@ -2233,7 +7523,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-styles": { "version": "4.2.1", @@ -4059,7 +9350,8 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/dashboard/src/core/devtools.ts b/dashboard/src/core/devtools.ts index 906c82f7da..77fc789451 100644 --- a/dashboard/src/core/devtools.ts +++ b/dashboard/src/core/devtools.ts @@ -7,30 +7,40 @@ :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. */ -import path = require('path') -import fs = require('fs') +import path = require('path'); +import fs = require('fs'); const ncp = require('ncp').ncp ncp.limit = 16 function setUpDevTools () { - const destinationFolderPath = path.join(path.dirname(__dirname), 'public', 'dashboard', 'devtools') + const destinationFolderPath = path.join( + path.dirname(__dirname), + 'public', + 'dashboard', + 'devtools' + ) const destinationFolderExists = fs.existsSync(destinationFolderPath) if (!destinationFolderExists) { - console.error(destinationFolderPath + ' folder doesn\'t exist, make sure you are in the right directory.') + console.error( + destinationFolderPath + + " folder doesn't exist, make sure you are in the right directory." + ) process.exit(1) } - const chromeDevTools = path.dirname(require.resolve('chrome-devtools-frontend/front_end/inspector.html')) + const chromeDevTools = path.dirname( + require.resolve('chrome-devtools-frontend/front_end/inspector.json') + ) console.log('Destination folder: ' + destinationFolderPath) ncp(chromeDevTools, destinationFolderPath, (err: any) => { if (err) { return console.error(err) } - console.log('Done!!!') }) + console.log('Done!!!') } setUpDevTools() diff --git a/dashboard/src/core/plugins/inspect_traffic.html b/dashboard/src/core/plugins/inspect_traffic.html index 3889c73b78..afd29d2551 100644 --- a/dashboard/src/core/plugins/inspect_traffic.html +++ b/dashboard/src/core/plugins/inspect_traffic.html @@ -7,12 +7,11 @@ :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. --> - + - - - - - - + + + + + diff --git a/dashboard/src/core/plugins/inspect_traffic.js b/dashboard/src/core/plugins/inspect_traffic.js index 3b60c5c0f0..3661cd6786 100644 --- a/dashboard/src/core/plugins/inspect_traffic.js +++ b/dashboard/src/core/plugins/inspect_traffic.js @@ -7,4 +7,7 @@ :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. */ -Root.Runtime.startApplication('inspect_traffic'); +import './devtools_app.js'; +import * as Startup from './startup/startup.js'; + +Startup.RuntimeInstantiator.startApplication('inspect_traffic'); diff --git a/dashboard/src/core/plugins/inspect_traffic.json b/dashboard/src/core/plugins/inspect_traffic.json index 31747bbbcd..fc9912b2ce 100644 --- a/dashboard/src/core/plugins/inspect_traffic.json +++ b/dashboard/src/core/plugins/inspect_traffic.json @@ -1,13 +1,21 @@ { - "modules" : [ - { "name": "inspector_main", "type": "autostart" }, - { "name": "emulation" }, - { "name": "mobile_throttling" }, - { "name": "cookie_table" }, - { "name": "har_importer" }, - { "name": "network" } - ], - "extends": "shell", - "has_html": true - } - \ No newline at end of file + "modules" : [ + { "name": "platform", "type": "autostart" }, + { "name": "main", "type": "autostart" }, + { "name": "components", "type": "autostart" }, + { "name": "ui", "type": "autostart" }, + { "name": "sdk", "type": "autostart" }, + { "name": "host", "type": "autostart" }, + { "name": "common", "type": "autostart" }, + { "name": "emulation", "type": "autostart" }, + { "name": "workspace", "type": "autostart" }, + { "name": "bindings", "type": "autostart" }, + { "name": "extensions", "type": "autostart" }, + { "name": "ui_lazy" }, + { "name": "components_lazy" }, + { "name": "network" }, + { "name": "source_frame" } + ], + "extends": "devtools_app", + "has_html": true +} diff --git a/dashboard/src/manifest.json b/dashboard/src/manifest.json index 75ed311dca..ef28d038cb 100644 --- a/dashboard/src/manifest.json +++ b/dashboard/src/manifest.json @@ -1,34 +1,34 @@ { - "name": "Proxy.py Dashboard", - "short_name": "Proxy.py Dashboard", - "start_url": "/dashboard/", - "display": "standalone", - "background_color": "#3E4EB8", - "theme_color": "#2F3BA2", - "icons": [{ - "src": "/dashboard/images/icons/icon-128x128.png", - "sizes": "128x128", - "type": "image/png" - }, { - "src": "/dashboard/images/icons/icon-144x144.png", - "sizes": "144x144", - "type": "image/png" - }, { - "src": "/dashboard/images/icons/icon-152x152.png", - "sizes": "152x152", - "type": "image/png" - }, { - "src": "/dashboard/images/icons/icon-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, { - "src": "/dashboard/images/icons/icon-256x256.png", - "sizes": "256x256", - "type": "image/png" - }, { - "src": "/dashboard/images/icons/icon-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ] + "name": "Proxy.py Dashboard", + "short_name": "Proxy.py Dashboard", + "start_url": "/dashboard/", + "display": "standalone", + "background_color": "#3E4EB8", + "theme_color": "#2F3BA2", + "icons": [{ + "src": "/dashboard/images/icons/icon-128x128.png", + "sizes": "128x128", + "type": "image/png" + }, { + "src": "/dashboard/images/icons/icon-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, { + "src": "/dashboard/images/icons/icon-152x152.png", + "sizes": "152x152", + "type": "image/png" + }, { + "src": "/dashboard/images/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, { + "src": "/dashboard/images/icons/icon-256x256.png", + "sizes": "256x256", + "type": "image/png" + }, { + "src": "/dashboard/images/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] } diff --git a/examples/https_connect_tunnel.py b/examples/https_connect_tunnel.py index 6bf504da12..ea2e49bcfb 100644 --- a/examples/https_connect_tunnel.py +++ b/examples/https_connect_tunnel.py @@ -9,6 +9,7 @@ :license: BSD, see LICENSE for more details. """ import time + from typing import Any, Optional from proxy.proxy import Proxy @@ -74,18 +75,15 @@ def handle_data(self, data: memoryview) -> Optional[bool]: def main() -> None: # This example requires `threadless=True` - pool = AcceptorPool( - flags=Proxy.initialize(port=12345, num_workers=1, threadless=True), - work_klass=HttpsConnectTunnelHandler, - ) - try: - pool.setup() - while True: - time.sleep(1) - except KeyboardInterrupt: - pass - finally: - pool.shutdown() + with AcceptorPool( + flags=Proxy.initialize(port=12345, num_workers=1, threadless=True), + work_klass=HttpsConnectTunnelHandler, + ): + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + pass if __name__ == '__main__': diff --git a/examples/ssl_echo_server.py b/examples/ssl_echo_server.py index b609abd199..5c46ef63a9 100644 --- a/examples/ssl_echo_server.py +++ b/examples/ssl_echo_server.py @@ -45,7 +45,7 @@ def handle_data(self, data: memoryview) -> Optional[bool]: def main() -> None: # This example requires `threadless=True` - pool = AcceptorPool( + with AcceptorPool( flags=Proxy.initialize( port=12345, num_workers=1, @@ -54,15 +54,12 @@ def main() -> None: certfile='https-signed-cert.pem', ), work_klass=EchoSSLServerHandler, - ) - try: - pool.setup() - while True: - time.sleep(1) - except KeyboardInterrupt: - pass - finally: - pool.shutdown() + ): + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + pass if __name__ == '__main__': diff --git a/examples/tcp_echo_server.py b/examples/tcp_echo_server.py index 16cf3fcb95..38d194cfd5 100644 --- a/examples/tcp_echo_server.py +++ b/examples/tcp_echo_server.py @@ -30,18 +30,15 @@ def handle_data(self, data: memoryview) -> Optional[bool]: def main() -> None: # This example requires `threadless=True` - pool = AcceptorPool( + with AcceptorPool( flags=Proxy.initialize(port=12345, num_workers=1, threadless=True), work_klass=EchoServerHandler, - ) - try: - pool.setup() - while True: - time.sleep(1) - except KeyboardInterrupt: - pass - finally: - pool.shutdown() + ): + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + pass if __name__ == '__main__': diff --git a/helper/chrome_with_rdp.sh b/helper/chrome_with_rdp.sh new file mode 100755 index 0000000000..1b59a464d7 --- /dev/null +++ b/helper/chrome_with_rdp.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# proxy.py +# ~~~~~~~~ +# ⚡⚡⚡ Fast, Lightweight, Programmable, TLS interception capable +# proxy server for Application debugging, testing and development. +# +# :copyright: (c) 2013-present by Abhinav Singh and contributors. +# :license: BSD, see LICENSE for more details. +# +# Usage +# ./chrome_with_proxy + +/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ + --no-first-run \ + --no-default-browser-check \ + --remote-debugging-port=9222 \ + --user-data-dir="$(mktemp -d -t 'chrome-remote_data_dir')" diff --git a/menubar/proxy.py.xcodeproj/project.pbxproj b/menubar/proxy.py.xcodeproj/project.pbxproj index 5c44621506..d86998c5c8 100644 --- a/menubar/proxy.py.xcodeproj/project.pbxproj +++ b/menubar/proxy.py.xcodeproj/project.pbxproj @@ -447,7 +447,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - PRODUCT_BUNDLE_IDENTIFIER = "com.abhinavsingh.proxy-py"; + PRODUCT_BUNDLE_IDENTIFIER = com.jaxl.proxy; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; @@ -471,7 +471,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - PRODUCT_BUNDLE_IDENTIFIER = "com.abhinavsingh.proxy-py"; + PRODUCT_BUNDLE_IDENTIFIER = com.jaxl.proxy; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; diff --git a/menubar/proxy.py.xcodeproj/project.xcworkspace/xcuserdata/abhinavsingh.xcuserdatad/UserInterfaceState.xcuserstate b/menubar/proxy.py.xcodeproj/project.xcworkspace/xcuserdata/abhinavsingh.xcuserdatad/UserInterfaceState.xcuserstate index f4e17991b460897ec013f5be4772e272a742d3d1..160c36502d539ca63700a3a1259e364e9cc1b9ac 100644 GIT binary patch delta 12370 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 W4;w39Fepm=Z`G&Wg#(hqn*ImsT0Zdr diff --git a/menubar/proxy.py/Info.plist b/menubar/proxy.py/Info.plist index ada1ded305..9e185bfbe8 100644 --- a/menubar/proxy.py/Info.plist +++ b/menubar/proxy.py/Info.plist @@ -20,8 +20,12 @@ 1.0 CFBundleVersion 1 + LSApplicationCategoryType + public.app-category.utilities LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) + LSUIElement + NSHumanReadableCopyright Copyright © 2013-present by Abhinav Singh and contributors. All rights reserved. NSMainStoryboardFile @@ -30,8 +34,6 @@ NSApplication NSSupportsAutomaticTermination - LSUIElement - NSSupportsSuddenTermination diff --git a/proxy/common/constants.py b/proxy/common/constants.py index 641478004d..ef413c4a54 100644 --- a/proxy/common/constants.py +++ b/proxy/common/constants.py @@ -10,6 +10,7 @@ """ import os import time +import secrets import pathlib import ipaddress @@ -60,7 +61,7 @@ DEFAULT_IPV6_HOSTNAME = ipaddress.IPv6Address('::1') DEFAULT_KEY_FILE = None DEFAULT_LOG_FILE = None -DEFAULT_LOG_FORMAT = '%(asctime)s - pid:%(process)d [%(levelname)-.1s] %(filename)s:%(funcName)s:%(lineno)d - %(message)s' +DEFAULT_LOG_FORMAT = '%(asctime)s - pid:%(process)d [%(levelname)-.1s] %(module)s.%(funcName)s:%(lineno)d - %(message)s' DEFAULT_LOG_LEVEL = 'INFO' DEFAULT_HTTP_ACCESS_LOG_FORMAT = '{client_ip}:{client_port} - ' + \ '{request_method} {server_host}:{server_port}{request_path} - ' + \ @@ -85,6 +86,10 @@ DEFAULT_HTTPS_PORT = 443 DEFAULT_MAX_SEND_SIZE = 16 * 1024 +DEFAULT_DEVTOOLS_DOC_URL = 'http://proxy' +DEFAULT_DEVTOOLS_FRAME_ID = secrets.token_hex(8) +DEFAULT_DEVTOOLS_LOADER_ID = secrets.token_hex(8) + DEFAULT_DATA_DIRECTORY_PATH = os.path.join(str(pathlib.Path.home()), '.proxy') # Cor plugins enabled by default or via flags diff --git a/proxy/core/acceptor/pool.py b/proxy/core/acceptor/pool.py index 0f1a28663e..6b50035833 100644 --- a/proxy/core/acceptor/pool.py +++ b/proxy/core/acceptor/pool.py @@ -15,7 +15,9 @@ from multiprocessing import connection from multiprocessing.reduction import send_handle + from typing import List, Optional, Type +from types import TracebackType from .acceptor import Acceptor from .work import Work @@ -88,6 +90,18 @@ def __init__( self.work_klass = work_klass self.event_queue: Optional[EventQueue] = event_queue + def __enter__(self) -> 'AcceptorPool': + self.setup() + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + self.shutdown() + def listen(self) -> None: self.socket = socket.socket(self.flags.family, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/proxy/core/acceptor/threadless.py b/proxy/core/acceptor/threadless.py index 8caf21739b..7d6e770e80 100644 --- a/proxy/core/acceptor/threadless.py +++ b/proxy/core/acceptor/threadless.py @@ -16,9 +16,9 @@ import selectors import contextlib import multiprocessing + from multiprocessing import connection from multiprocessing.reduction import recv_handle - from typing import Dict, Optional, Tuple, List, Generator, Any, Type from .work import Work diff --git a/proxy/core/base/tcp_server.py b/proxy/core/base/tcp_server.py index 0eda82ba21..1db40b1662 100644 --- a/proxy/core/base/tcp_server.py +++ b/proxy/core/base/tcp_server.py @@ -8,35 +8,44 @@ :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. """ -from abc import abstractmethod import socket +import logging import selectors +from abc import abstractmethod from typing import Dict, Any, Optional from proxy.core.acceptor import Work from proxy.common.types import Readables, Writables +logger = logging.getLogger(__name__) + class BaseTcpServerHandler(Work): """BaseTcpServerHandler implements Work interface. + BaseTcpServerHandler lifecycle is controlled by Threadless core + using asyncio. If you want to also support threaded mode, also + implement the optional run() method from Work class. + An instance of BaseTcpServerHandler is created for each client - connection. BaseServerHandler lifecycle is controlled by - Threadless core using asyncio. + connection. BaseTcpServerHandler ensures that server is always + ready to accept new data from the client. It also ensures, client + is ready to accept new data before flushing data to it. - BaseServerHandler ensures that pending buffers are flushed - before client connection is closed. + Most importantly, BaseTcpServerHandler ensures that pending buffers + to the client are flushed before connection is closed. Implementations must provide: - a) handle_data(data: memoryview) - c) (optionally) initialize, is_inactive and shutdown methods + a) handle_data(data: memoryview) implementation + b) Optionally, also implement other Work method + e.g. initialize, is_inactive, shutdown """ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self.must_flush_before_shutdown = False - print('Connection accepted from {0}'.format(self.client.addr)) + logger.debug('Connection accepted from {0}'.format(self.client.addr)) @abstractmethod def handle_data(self, data: memoryview) -> Optional[bool]: @@ -64,54 +73,63 @@ def handle_events( writables: Writables, ) -> bool: """Return True to shutdown work.""" - do_shutdown = False + teardown = self.handle_writables( + writables, + ) or self.handle_readables(readables) + if teardown: + logger.debug( + 'Shutting down client {0} connection'.format( + self.client.addr, + ), + ) + return teardown + + def handle_writables(self, writables: Writables) -> bool: + teardown = False + if self.client.connection in writables and self.client.has_buffer(): + logger.debug( + 'Flushing buffer to client {0}'.format(self.client.addr), + ) + self.client.flush() + if self.must_flush_before_shutdown is True: + teardown = True + self.must_flush_before_shutdown = False + return teardown + + def handle_readables(self, readables: Readables) -> bool: + teardown = False if self.client.connection in readables: - try: - data = self.client.recv() - if data is None: - # Client closed connection, signal shutdown - print( - 'Connection closed by client {0}'.format( + data = self.client.recv(self.flags.client_recvbuf_size) + if data is None: + # Client closed connection, signal shutdown + logger.debug( + 'Connection closed by client {0}'.format( + self.client.addr, + ), + ) + teardown = True + else: + r = self.handle_data(data) + if isinstance(r, bool) and r is True: + logger.debug( + 'Implementation signaled shutdown for client {0}'.format( self.client.addr, ), ) - do_shutdown = True - else: - r = self.handle_data(data) - if isinstance(r, bool) and r is True: - print( - 'Implementation signaled shutdown for client {0}'.format( + if self.client.has_buffer(): + logger.debug( + 'Client {0} has pending buffer, will be flushed before shutting down'.format( self.client.addr, ), ) - if self.client.has_buffer(): - print( - 'Client {0} has pending buffer, will be flushed before shutting down'.format( - self.client.addr, - ), - ) - self.must_flush_before_shutdown = True - else: - do_shutdown = True - except ConnectionResetError: - print( - 'Connection reset by client {0}'.format( - self.client.addr, - ), - ) - do_shutdown = True - - if self.client.connection in writables: - print('Flushing buffer to client {0}'.format(self.client.addr)) - self.client.flush() - if self.must_flush_before_shutdown is True: - do_shutdown = True - self.must_flush_before_shutdown = False - - if do_shutdown: - print( - 'Shutting down client {0} connection'.format( - self.client.addr, - ), - ) - return do_shutdown + self.must_flush_before_shutdown = True + else: + teardown = True + # except ConnectionResetError: + # logger.debug( + # 'Connection reset by client {0}'.format( + # self.client.addr, + # ), + # ) + # teardown = True + return teardown diff --git a/proxy/core/base/tcp_tunnel.py b/proxy/core/base/tcp_tunnel.py index 8703247cf2..6763a96fce 100644 --- a/proxy/core/base/tcp_tunnel.py +++ b/proxy/core/base/tcp_tunnel.py @@ -22,7 +22,15 @@ class BaseTcpTunnelHandler(BaseTcpServerHandler): - """Base TCP tunnel interface.""" + """BaseTcpTunnelHandler build on-top of BaseTcpServerHandler work klass. + + On-top of BaseTcpServerHandler implementation, + BaseTcpTunnelHandler introduces an upstream TcpServerConnection + and adds it to the core event loop when needed. + + Currently, implementations must call connect_upstream from within + handle_data. See HttpsConnectTunnelHandler for example usage. + """ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) diff --git a/proxy/http/handler.py b/proxy/http/handler.py index 41ec608f86..07715c9577 100644 --- a/proxy/http/handler.py +++ b/proxy/http/handler.py @@ -8,7 +8,6 @@ :copyright: (c) 2013-present by Abhinav Singh and contributors. :license: BSD, see LICENSE for more details. """ -import argparse import socket import selectors import ssl @@ -17,8 +16,7 @@ import errno import logging -from typing import Tuple, List, Union, Optional, Generator, Dict -from uuid import UUID +from typing import Tuple, List, Union, Optional, Generator, Dict, Any from .plugin import HttpProtocolHandlerPlugin from .parser import HttpParser, httpParserStates, httpParserTypes @@ -26,8 +24,7 @@ from ..common.types import Readables, Writables from ..common.utils import wrap_socket -from ..core.acceptor.work import Work -from ..core.event import EventQueue +from ..core.base import BaseTcpServerHandler from ..core.connection import TcpClientConnection from ..common.flag import flags from ..common.constants import DEFAULT_CLIENT_RECVBUF_SIZE, DEFAULT_KEY_FILE, DEFAULT_TIMEOUT @@ -62,52 +59,40 @@ 'data sent or received by the client.', ) +SelectedEventsGeneratorType = Generator[ + Tuple[Readables, Writables], + None, None, +] -class HttpProtocolHandler(Work): + +class HttpProtocolHandler(BaseTcpServerHandler): """HTTP, HTTPS, HTTP2, WebSockets protocol handler. Accepts `Client` connection and delegates to HttpProtocolHandlerPlugin. """ - def __init__( - self, client: TcpClientConnection, - flags: argparse.Namespace, - event_queue: Optional[EventQueue] = None, - uid: Optional[UUID] = None, - ): - super().__init__(client, flags, event_queue, uid) - + def __init__(self, *args: Any, **kwargs: Any): + super().__init__(*args, **kwargs) self.start_time: float = time.time() self.last_activity: float = self.start_time self.request: HttpParser = HttpParser(httpParserTypes.REQUEST_PARSER) self.response: HttpParser = HttpParser(httpParserTypes.RESPONSE_PARSER) - self.selector = selectors.DefaultSelector() - self.client: TcpClientConnection = client + self.selector: Optional[selectors.DefaultSelector] = None + if not self.flags.threadless: + self.selector = selectors.DefaultSelector() self.plugins: Dict[str, HttpProtocolHandlerPlugin] = {} - def encryption_enabled(self) -> bool: - return self.flags.keyfile is not None and \ - self.flags.certfile is not None - - def optionally_wrap_socket( - self, conn: socket.socket, - ) -> Union[ssl.SSLSocket, socket.socket]: - """Attempts to wrap accepted client connection using provided certificates. - - Shutdown and closes client connection upon error. - """ - if self.encryption_enabled(): - assert self.flags.keyfile and self.flags.certfile - # TODO(abhinavsingh): Insecure TLS versions must not be accepted by default - conn = wrap_socket(conn, self.flags.keyfile, self.flags.certfile) - return conn + ## + # initialize, is_inactive, shutdown, get_events, handle_events + # overrides Work class definitions. + ## def initialize(self) -> None: """Optionally upgrades connection to HTTPS, set conn in non-blocking mode and initializes plugins.""" - conn = self.optionally_wrap_socket(self.client.connection) + conn = self._optionally_wrap_socket(self.client.connection) conn.setblocking(False) # Update client connection reference if connection was wrapped - if self.encryption_enabled(): + if self._encryption_enabled(): self.client = TcpClientConnection(conn=conn, addr=self.client.addr) if b'HttpProtocolHandlerPlugin' in self.flags.plugins: for klass in self.flags.plugins[b'HttpProtocolHandlerPlugin']: @@ -123,16 +108,52 @@ def initialize(self) -> None: def is_inactive(self) -> bool: if not self.client.has_buffer() and \ - self.connection_inactive_for() > self.flags.timeout: + self._connection_inactive_for() > self.flags.timeout: return True return False + def shutdown(self) -> None: + try: + # Flush pending buffer if any + # TODO: This can block as it register, select, unregister. + # _flush is only for use with threaded mode. In threadless + # mode BaseTcpServerHandler provides must_flush_before_shutdown + # implementation. + if self.selector: + self._flush() + else: + # Call flush for threadless mode assuming client is write ready + # This may fail or block. Using BaseTcpServerHandler will + # solve this issue. + self.client.flush() + + # Invoke plugin.on_client_connection_close + for plugin in self.plugins.values(): + plugin.on_client_connection_close() + + logger.debug( + 'Closing client connection %r ' + 'at address %r has buffer %s' % + (self.client.connection, self.client.addr, self.client.has_buffer()), + ) + + conn = self.client.connection + # Unwrap if wrapped before shutdown. + if self._encryption_enabled() and \ + isinstance(self.client.connection, ssl.SSLSocket): + conn = self.client.connection.unwrap() + conn.shutdown(socket.SHUT_WR) + logger.debug('Client connection shutdown successful') + except OSError: + pass + finally: + self.client.connection.close() + logger.debug('Client connection closed') + super().shutdown() + def get_events(self) -> Dict[socket.socket, int]: - events: Dict[socket.socket, int] = { - self.client.connection: selectors.EVENT_READ, - } - if self.client.has_buffer(): - events[self.client.connection] |= selectors.EVENT_WRITE + # Get default client events + events: Dict[socket.socket, int] = super().get_events() # HttpProtocolHandlerPlugin.get_descriptors for plugin in self.plugins.values(): plugin_read_desc, plugin_write_desc = plugin.get_descriptors() @@ -148,6 +169,7 @@ def get_events(self) -> Dict[socket.socket, int]: events[w] |= selectors.EVENT_WRITE return events + # We override super().handle_events and never call it def handle_events( self, readables: Readables, @@ -178,65 +200,64 @@ def handle_events( return False - def shutdown(self) -> None: - try: - # Flush pending buffer if any - self.flush() + def handle_data(self, data: memoryview) -> Optional[bool]: + if data is None: + logger.debug('Client closed connection, tearing down...') + self.client.closed = True + return True - # Invoke plugin.on_client_connection_close + try: + # HttpProtocolHandlerPlugin.on_client_data + # Can raise HttpProtocolException to teardown the connection for plugin in self.plugins.values(): - plugin.on_client_connection_close() - + optional_data = plugin.on_client_data(data) + if optional_data is None: + break + data = optional_data + # Don't parse incoming data any further after 1st request has completed. + # + # This specially does happen for pipeline requests. + # + # Plugins can utilize on_client_data for such cases and + # apply custom logic to handle request data sent after 1st + # valid request. + if data and self.request.state != httpParserStates.COMPLETE: + # Parse http request + # TODO(abhinavsingh): Remove .tobytes after parser is + # memoryview compliant + self.request.parse(data.tobytes()) + if self.request.state == httpParserStates.COMPLETE: + # Invoke plugin.on_request_complete + for plugin in self.plugins.values(): + upgraded_sock = plugin.on_request_complete() + if isinstance(upgraded_sock, ssl.SSLSocket): + logger.debug( + 'Updated client conn to %s', upgraded_sock, + ) + self.client._conn = upgraded_sock + for plugin_ in self.plugins.values(): + if plugin_ != plugin: + plugin_.client._conn = upgraded_sock + elif isinstance(upgraded_sock, bool) and upgraded_sock is True: + return True + except HttpProtocolException as e: logger.debug( - 'Closing client connection %r ' - 'at address %r has buffer %s' % - (self.client.connection, self.client.addr, self.client.has_buffer()), + 'HttpProtocolException type raised', ) - - conn = self.client.connection - # Unwrap if wrapped before shutdown. - if self.encryption_enabled() and \ - isinstance(self.client.connection, ssl.SSLSocket): - conn = self.client.connection.unwrap() - conn.shutdown(socket.SHUT_WR) - logger.debug('Client connection shutdown successful') - except OSError: - pass - finally: - self.client.connection.close() - logger.debug('Client connection closed') - super().shutdown() - - def connection_inactive_for(self) -> float: - return time.time() - self.last_activity - - def flush(self) -> None: - if not self.client.has_buffer(): - return - try: - self.selector.register( - self.client.connection, - selectors.EVENT_WRITE, - ) - while self.client.has_buffer(): - ev: List[ - Tuple[selectors.SelectorKey, int] - ] = self.selector.select(timeout=1) - if len(ev) == 0: - continue - self.client.flush() - except BrokenPipeError: - pass - finally: - self.selector.unregister(self.client.connection) + response: Optional[memoryview] = e.response(self.request) + if response: + self.client.queue(response) + return True + return False def handle_writables(self, writables: Writables) -> bool: - if self.client.has_buffer() and self.client.connection in writables: + if self.client.connection in writables and self.client.has_buffer(): logger.debug('Client is ready for writes, flushing buffer') self.last_activity = time.time() # TODO(abhinavsingh): This hook could just reside within server recv block # instead of invoking when flushed to client. + # # Invoke plugin.on_response_chunk chunk = self.client.buffer for plugin in self.plugins.values(): @@ -245,7 +266,10 @@ def handle_writables(self, writables: Writables) -> bool: break try: - self.client.flush() + # Call super() for client flush + teardown = super().handle_writables(writables) + if teardown: + return True except BrokenPipeError: logger.error( 'BrokenPipeError when flushing buffer for client', @@ -261,7 +285,9 @@ def handle_readables(self, readables: Readables) -> bool: logger.debug('Client is ready for reads, reading') self.last_activity = time.time() try: - client_data = self.client.recv(self.flags.client_recvbuf_size) + teardown = super().handle_readables(readables) + if teardown: + return teardown except ssl.SSLWantReadError: # Try again later logger.warning( 'SSLWantReadError encountered while reading from client, will retry ...', @@ -276,85 +302,17 @@ def handle_readables(self, readables: Readables) -> bool: (self.client.tag, self.client.connection, e), ) return True - - if client_data is None: - logger.debug('Client closed connection, tearing down...') - self.client.closed = True - return True - - try: - # HttpProtocolHandlerPlugin.on_client_data - # Can raise HttpProtocolException to teardown the connection - for plugin in self.plugins.values(): - client_data = plugin.on_client_data(client_data) - if client_data is None: - break - - # Don't parse incoming data any further after 1st request has completed. - # - # This specially does happen for pipeline requests. - # - # Plugins can utilize on_client_data for such cases and - # apply custom logic to handle request data sent after 1st - # valid request. - if client_data and self.request.state != httpParserStates.COMPLETE: - # Parse http request - # TODO(abhinavsingh): Remove .tobytes after parser is - # memoryview compliant - self.request.parse(client_data.tobytes()) - if self.request.state == httpParserStates.COMPLETE: - # Invoke plugin.on_request_complete - for plugin in self.plugins.values(): - upgraded_sock = plugin.on_request_complete() - if isinstance(upgraded_sock, ssl.SSLSocket): - logger.debug( - 'Updated client conn to %s', upgraded_sock, - ) - self.client._conn = upgraded_sock - for plugin_ in self.plugins.values(): - if plugin_ != plugin: - plugin_.client._conn = upgraded_sock - elif isinstance(upgraded_sock, bool) and upgraded_sock is True: - return True - except HttpProtocolException as e: - logger.debug( - 'HttpProtocolException type raised', - ) - response: Optional[memoryview] = e.response(self.request) - if response: - self.client.queue(response) - return True return False - @contextlib.contextmanager - def selected_events(self) -> \ - Generator[ - Tuple[Readables, Writables], - None, None, - ]: - events = self.get_events() - for fd in events: - self.selector.register(fd, events[fd]) - ev = self.selector.select(timeout=1) - readables = [] - writables = [] - for key, mask in ev: - if mask & selectors.EVENT_READ: - readables.append(key.fileobj) - if mask & selectors.EVENT_WRITE: - writables.append(key.fileobj) - yield (readables, writables) - for fd in events: - self.selector.unregister(fd) - - def run_once(self) -> bool: - with self.selected_events() as (readables, writables): - teardown = self.handle_events(readables, writables) - if teardown: - return True - return False + ## + # run() is here to maintain backward compatibility for threaded mode + ## def run(self) -> None: + """run() method is not used when in --threadless mode. + + This is here just to maintain backward compatibility with threaded mode. + """ try: self.initialize() while True: @@ -365,7 +323,7 @@ def run(self) -> None: 'between client and server connection, tearing down...', ) break - teardown = self.run_once() + teardown = self._run_once() if teardown: break except KeyboardInterrupt: # pragma: no cover @@ -379,3 +337,73 @@ def run(self) -> None: ) finally: self.shutdown() + + ## + # Internal methods + ## + + def _encryption_enabled(self) -> bool: + return self.flags.keyfile is not None and \ + self.flags.certfile is not None + + def _optionally_wrap_socket( + self, conn: socket.socket, + ) -> Union[ssl.SSLSocket, socket.socket]: + """Attempts to wrap accepted client connection using provided certificates. + + Shutdown and closes client connection upon error. + """ + if self._encryption_enabled(): + assert self.flags.keyfile and self.flags.certfile + # TODO(abhinavsingh): Insecure TLS versions must not be accepted by default + conn = wrap_socket(conn, self.flags.keyfile, self.flags.certfile) + return conn + + @contextlib.contextmanager + def _selected_events(self) -> SelectedEventsGeneratorType: + assert self.selector + events = self.get_events() + for fd in events: + self.selector.register(fd, events[fd]) + ev = self.selector.select(timeout=1) + readables = [] + writables = [] + for key, mask in ev: + if mask & selectors.EVENT_READ: + readables.append(key.fileobj) + if mask & selectors.EVENT_WRITE: + writables.append(key.fileobj) + yield (readables, writables) + for fd in events: + self.selector.unregister(fd) + + def _run_once(self) -> bool: + with self._selected_events() as (readables, writables): + teardown = self.handle_events(readables, writables) + if teardown: + return True + return False + + def _flush(self) -> None: + assert self.selector + if not self.client.has_buffer(): + return + try: + self.selector.register( + self.client.connection, + selectors.EVENT_WRITE, + ) + while self.client.has_buffer(): + ev: List[ + Tuple[selectors.SelectorKey, int] + ] = self.selector.select(timeout=1) + if len(ev) == 0: + continue + self.client.flush() + except BrokenPipeError: + pass + finally: + self.selector.unregister(self.client.connection) + + def _connection_inactive_for(self) -> float: + return time.time() - self.last_activity diff --git a/proxy/http/inspector/devtools.py b/proxy/http/inspector/devtools.py index 800d88024d..9e4bd8ca6c 100644 --- a/proxy/http/inspector/devtools.py +++ b/proxy/http/inspector/devtools.py @@ -20,7 +20,7 @@ from ...common.utils import bytes_, text_ from ...core.event import EventSubscriber from ...common.flag import flags -from ...common.constants import DEFAULT_DEVTOOLS_WS_PATH +from ...common.constants import DEFAULT_DEVTOOLS_WS_PATH, DEFAULT_DEVTOOLS_DOC_URL logger = logging.getLogger(__name__) @@ -44,8 +44,6 @@ class DevtoolsProtocolPlugin(HttpWebServerBasePlugin): - Core events unrelated to DevTools protocol are dropped. """ - DOC_URL = 'http://dashboard.proxy.py' - def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self.subscriber = EventSubscriber(self.event_queue) @@ -82,7 +80,6 @@ def handle_devtools_message(self, message: Dict[str, Any]) -> None: frame = WebsocketFrame() frame.fin = True frame.opcode = websocketOpcodes.TEXT_FRAME - # logger.info(message) method = message['method'] if method in ( @@ -99,7 +96,7 @@ def handle_devtools_message(self, message: Dict[str, Any]) -> None: 'frameTree': { 'frame': { 'id': 1, - 'url': DevtoolsProtocolPlugin.DOC_URL, + 'url': DEFAULT_DEVTOOLS_DOC_URL, 'mimeType': 'other', }, 'childFrames': [], @@ -118,7 +115,6 @@ def handle_devtools_message(self, message: Dict[str, Any]) -> None: else: logging.warning('Unhandled devtools method %s', method) data = {} - data['id'] = message['id'] frame.data = bytes_(json.dumps(data)) self.client.queue(memoryview(frame.build())) diff --git a/proxy/http/inspector/transformer.py b/proxy/http/inspector/transformer.py index ebc5ddcede..2512a48c35 100644 --- a/proxy/http/inspector/transformer.py +++ b/proxy/http/inspector/transformer.py @@ -9,22 +9,22 @@ :license: BSD, see LICENSE for more details. """ import json -import secrets import time from typing import Any, Dict from ..websocket import WebsocketFrame -from ...common.constants import PROXY_PY_START_TIME +from ...common.constants import PROXY_PY_START_TIME, DEFAULT_DEVTOOLS_DOC_URL +from ...common.constants import DEFAULT_DEVTOOLS_FRAME_ID, DEFAULT_DEVTOOLS_LOADER_ID from ...common.utils import bytes_ from ...core.connection import TcpClientConnection from ...core.event import eventNames class CoreEventsToDevtoolsProtocol: + """Open in Chrome - DOC_URL = 'http://dashboard.proxy.py' - FRAME_ID = secrets.token_hex(8) - LOADER_ID = secrets.token_hex(8) + devtools://devtools/bundled/inspector.html?ws=localhost:8899/devtools + """ RESPONSES: Dict[str, bytes] = {} @@ -61,90 +61,100 @@ def transformer( def request_complete(event: Dict[str, Any]) -> Dict[str, Any]: now = time.time() return { - 'requestId': event['request_id'], - 'frameId': CoreEventsToDevtoolsProtocol.FRAME_ID, - 'loaderId': CoreEventsToDevtoolsProtocol.LOADER_ID, - 'documentURL': CoreEventsToDevtoolsProtocol.DOC_URL, - 'timestamp': now - PROXY_PY_START_TIME, - 'wallTime': now, - 'hasUserGesture': False, - 'type': event['event_payload']['headers']['content-type'] - if 'content-type' in event['event_payload']['headers'] - else 'Other', - # TODO(abhinavsingh): Bring this inline with devtools protocol 'method': 'Network.requestWillBeSent', - 'request': { - 'url': event['event_payload']['url'], - 'method': event['event_payload']['method'], - 'headers': event['event_payload']['headers'], - 'postData': event['event_payload']['body'], - 'initialPriority': 'High', - 'urlFragment': '', - 'mixedContentType': 'none', - }, - 'initiator': { - 'type': 'other', + 'params': { + 'requestId': event['request_id'], + 'frameId': DEFAULT_DEVTOOLS_FRAME_ID, + 'loaderId': DEFAULT_DEVTOOLS_LOADER_ID, + 'documentURL': DEFAULT_DEVTOOLS_DOC_URL, + 'timestamp': now - PROXY_PY_START_TIME, + 'wallTime': now, + 'hasUserGesture': False, + 'type': event['event_payload']['headers']['content-type'] + if 'content-type' in event['event_payload']['headers'] + else 'Other', + 'request': { + 'url': event['event_payload']['url'], + 'method': event['event_payload']['method'], + 'headers': event['event_payload']['headers'], + 'postData': event['event_payload']['body'], + 'initialPriority': 'High', + 'urlFragment': '', + 'mixedContentType': 'none', + }, + 'initiator': { + 'type': 'other', + }, }, } @staticmethod def response_headers_complete(event: Dict[str, Any]) -> Dict[str, Any]: return { - 'requestId': event['request_id'], - 'frameId': CoreEventsToDevtoolsProtocol.FRAME_ID, - 'loaderId': CoreEventsToDevtoolsProtocol.LOADER_ID, - 'timestamp': time.time(), - 'type': event['event_payload']['headers']['content-type'] - if event['event_payload']['headers'].has_header('content-type') - else 'Other', - 'response': { - 'url': '', - 'status': '', - 'statusText': '', - 'headers': '', - 'headersText': '', - 'mimeType': '', - 'connectionReused': True, - 'connectionId': '', - 'encodedDataLength': '', - 'fromDiskCache': False, - 'fromServiceWorker': False, - 'timing': { - 'requestTime': '', - 'proxyStart': -1, - 'proxyEnd': -1, - 'dnsStart': -1, - 'dnsEnd': -1, - 'connectStart': -1, - 'connectEnd': -1, - 'sslStart': -1, - 'sslEnd': -1, - 'workerStart': -1, - 'workerReady': -1, - 'sendStart': 0, - 'sendEnd': 0, - 'receiveHeadersEnd': 0, + 'method': 'Network.responseReceived', + 'params': { + 'requestId': event['request_id'], + 'frameId': DEFAULT_DEVTOOLS_FRAME_ID, + 'loaderId': DEFAULT_DEVTOOLS_LOADER_ID, + 'timestamp': time.time(), + 'type': event['event_payload']['headers']['content-type'] + if event['event_payload']['headers'].has_header('content-type') + else 'Other', + 'response': { + 'url': '', + 'status': '', + 'statusText': '', + 'headers': '', + 'headersText': '', + 'mimeType': '', + 'connectionReused': True, + 'connectionId': '', + 'encodedDataLength': '', + 'fromDiskCache': False, + 'fromServiceWorker': False, + 'timing': { + 'requestTime': '', + 'proxyStart': -1, + 'proxyEnd': -1, + 'dnsStart': -1, + 'dnsEnd': -1, + 'connectStart': -1, + 'connectEnd': -1, + 'sslStart': -1, + 'sslEnd': -1, + 'workerStart': -1, + 'workerReady': -1, + 'sendStart': 0, + 'sendEnd': 0, + 'receiveHeadersEnd': 0, + }, + 'requestHeaders': '', + 'remoteIPAddress': '', + 'remotePort': '', }, - 'requestHeaders': '', - 'remoteIPAddress': '', - 'remotePort': '', }, } @staticmethod def response_chunk_received(event: Dict[str, Any]) -> Dict[str, Any]: return { - 'requestId': event['request_id'], - 'timestamp': time.time(), - 'dataLength': event['event_payload']['chunk_size'], - 'encodedDataLength': event['event_payload']['encoded_chunk_size'], + 'method': 'Network.dataReceived', + 'params': { + 'requestId': event['request_id'], + 'timestamp': time.time(), + 'dataLength': event['event_payload']['chunk_size'], + 'encodedDataLength': event['event_payload']['encoded_chunk_size'], + }, } @staticmethod def response_complete(event: Dict[str, Any]) -> Dict[str, Any]: return { - 'requestId': event['request_id'], - 'timestamp': time.time(), - 'encodedDataLength': event['event_payload']['encoded_response_size'], - 'shouldReportCorbBlocking': False, + 'method': 'Network.loadingFinished', + 'params': { + 'requestId': event['request_id'], + 'timestamp': time.time(), + 'encodedDataLength': event['event_payload']['encoded_response_size'], + 'shouldReportCorbBlocking': False, + }, } diff --git a/proxy/http/proxy/server.py b/proxy/http/proxy/server.py index ec0a60676d..67f7989846 100644 --- a/proxy/http/proxy/server.py +++ b/proxy/http/proxy/server.py @@ -121,7 +121,7 @@ def __init__( ) -> None: super().__init__(*args, **kwargs) self.start_time: float = time.time() - self.server: Optional[TcpServerConnection] = None + self.upstream: Optional[TcpServerConnection] = None self.response: HttpParser = HttpParser(httpParserTypes.RESPONSE_PARSER) self.pipeline_request: Optional[HttpParser] = None self.pipeline_response: Optional[HttpParser] = None @@ -151,11 +151,11 @@ def get_descriptors( r: List[socket.socket] = [] w: List[socket.socket] = [] - if self.server and not self.server.closed and self.server.connection: - r.append(self.server.connection) - if self.server and not self.server.closed and \ - self.server.has_buffer() and self.server.connection: - w.append(self.server.connection) + if self.upstream and not self.upstream.closed and self.upstream.connection: + r.append(self.upstream.connection) + if self.upstream and not self.upstream.closed and \ + self.upstream.has_buffer() and self.upstream.connection: + w.append(self.upstream.connection) # TODO(abhinavsingh): We need to keep a mapping of plugin and # descriptors registered by them, so that within write/read blocks @@ -168,7 +168,7 @@ def get_descriptors( return r, w def write_to_descriptors(self, w: Writables) -> bool: - if (self.server and self.server.connection not in w) or not self.server: + if (self.upstream and self.upstream.connection not in w) or not self.upstream: # Currently, we just call write/read block of each plugins. It is # plugins responsibility to ignore this callback, if passed descriptors # doesn't contain the descriptor they registered. @@ -177,12 +177,12 @@ def write_to_descriptors(self, w: Writables) -> bool: if teardown: return True elif self.request.has_host() and \ - self.server and not self.server.closed and \ - self.server.has_buffer() and \ - self.server.connection in w: + self.upstream and not self.upstream.closed and \ + self.upstream.has_buffer() and \ + self.upstream.connection in w: logger.debug('Server is write ready, flushing buffer') try: - self.server.flush() + self.upstream.flush() except ssl.SSLWantWriteError: logger.warning( 'SSLWantWriteError while trying to flush to server, will retry', @@ -201,7 +201,11 @@ def write_to_descriptors(self, w: Writables) -> bool: return False def read_from_descriptors(self, r: Readables) -> bool: - if (self.server and self.server.connection not in r) or not self.server: + if ( + self.upstream and not + self.upstream.closed and + self.upstream.connection not in r + ) or not self.upstream: # Currently, we just call write/read block of each plugins. It is # plugins responsibility to ignore this callback, if passed descriptors # doesn't contain the descriptor they registered for. @@ -210,17 +214,17 @@ def read_from_descriptors(self, r: Readables) -> bool: if teardown: return True elif self.request.has_host() \ - and self.server \ - and not self.server.closed \ - and self.server.connection in r: + and self.upstream \ + and not self.upstream.closed \ + and self.upstream.connection in r: logger.debug('Server is ready for reads, reading...') try: - raw = self.server.recv(self.flags.server_recvbuf_size) + raw = self.upstream.recv(self.flags.server_recvbuf_size) except TimeoutError as e: if e.errno == errno.ETIMEDOUT: logger.warning( '%s:%d timed out on recv' % - self.server.addr, + self.upstream.addr, ) return True raise e @@ -231,7 +235,7 @@ def read_from_descriptors(self, r: Readables) -> bool: if e.errno == errno.EHOSTUNREACH: logger.warning( '%s:%d unreachable on recv' % - self.server.addr, + self.upstream.addr, ) return True if e.errno == errno.ECONNRESET: @@ -239,7 +243,7 @@ def read_from_descriptors(self, r: Readables) -> bool: else: logger.exception( 'Exception while receiving from %s connection %r with reason %r' % - (self.server.tag, self.server.connection, e), + (self.upstream.tag, self.upstream.connection, e), ) return True @@ -263,8 +267,9 @@ def read_from_descriptors(self, r: Readables) -> bool: else: # TODO(abhinavsingh): Remove .tobytes after parser is # memoryview compliant - self.response.parse(raw.tobytes()) - self.emit_response_events() + chunk = raw.tobytes() + self.response.parse(chunk) + self.emit_response_events(len(chunk)) else: self.response.total_size += len(raw) # queue raw data for client @@ -280,8 +285,8 @@ def on_client_connection_close(self) -> None: 'client_port': self.client.addr[1], 'request_method': text_(self.request.method), 'request_path': text_(self.request.path), - 'server_host': text_(self.server.addr[0] if self.server else None), - 'server_port': text_(self.server.addr[1] if self.server else None), + 'server_host': text_(self.upstream.addr[0] if self.upstream else None), + 'server_port': text_(self.upstream.addr[1] if self.upstream else None), 'response_bytes': self.response.total_size, 'connection_time_ms': '%.2f' % ((time.time() - self.start_time) * 1000), 'response_code': text_(self.response.code), @@ -312,23 +317,23 @@ def on_client_connection_close(self) -> None: plugin.on_upstream_connection_close() # If server was never initialized, return - if self.server is None: + if self.upstream is None: return try: try: - self.server.connection.shutdown(socket.SHUT_WR) + self.upstream.connection.shutdown(socket.SHUT_WR) except OSError: pass finally: # TODO: Unwrap if wrapped before close? - self.server.connection.close() + self.upstream.connection.close() except TcpConnectionUninitializedException: pass finally: logger.debug( 'Closed server connection, has buffer %s' % - self.server.has_buffer(), + self.upstream.has_buffer(), ) def access_log(self, log_attrs: Dict[str, Any]) -> None: @@ -363,13 +368,13 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]: # # We only call handle_client_data once original request has been # completely received - if not self.server: + if not self.upstream: for plugin in self.plugins.values(): o = plugin.handle_client_data(raw) if o is None: return None raw = o - elif self.server and not self.server.closed: + elif self.upstream and not self.upstream.closed: # For http proxy requests, handle pipeline case. # We also handle pipeline scenario for https proxy # requests is TLS interception is enabled. @@ -382,7 +387,7 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]: # Previous pipelined request was a WebSocket # upgrade request. Incoming client data now # must be treated as WebSocket protocol packets. - self.server.queue(raw) + self.upstream.queue(raw) return None if self.pipeline_request is None: @@ -403,7 +408,7 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]: assert self.pipeline_request is not None # TODO(abhinavsingh): Remove memoryview wrapping here after # parser is fully memoryview compliant - self.server.queue( + self.upstream.queue( memoryview( self.pipeline_request.build(), ), @@ -413,7 +418,7 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]: # For scenarios where we cannot peek into the data, # simply queue for upstream server. else: - self.server.queue(raw) + self.upstream.queue(raw) return None return raw @@ -453,7 +458,7 @@ def on_request_complete(self) -> Union[socket.socket, bool]: # For https requests, respond back with tunnel established response. # Optionally, setup interceptor if TLS interception is enabled. - if self.server: + if self.upstream: if self.request.method == httpMethods.CONNECT: self.client.queue( HttpProxyPlugin.PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT, @@ -480,7 +485,7 @@ def on_request_complete(self) -> Union[socket.socket, bool]: [(b'Via', b'1.1 %s' % PROXY_AGENT_HEADER_VALUE)], ) # Disable args.disable_headers before dispatching to upstream - self.server.queue( + self.upstream.queue( memoryview( self.request.build( disable_headers=self.flags.disable_headers, @@ -503,7 +508,7 @@ def handle_pipeline_response(self, raw: memoryview) -> None: def connect_upstream(self) -> None: host, port = self.request.host, self.request.port if host and port: - self.server = TcpServerConnection(text_(host), port) + self.upstream = TcpServerConnection(text_(host), port) try: logger.debug( 'Connecting to upstream %s:%s' % @@ -519,12 +524,12 @@ def connect_upstream(self) -> None: break # Connect with overridden upstream IP and source address # if any of the plugin returned a non-null value. - self.server.connect( + self.upstream.connect( addr=None if not upstream_ip else ( upstream_ip, port, ), source_address=source_addr, ) - self.server.connection.setblocking(False) + self.upstream.connection.setblocking(False) logger.debug( 'Connected to upstream %s:%s' % (text_(host), port), @@ -533,7 +538,7 @@ def connect_upstream(self) -> None: logger.exception( 'Unable to connect with upstream server', exc_info=e, ) - self.server.closed = True + self.upstream.closed = True raise ProxyConnectionFailed(text_(host), port, repr(e)) from e else: logger.exception('Both host and port must exist') @@ -681,16 +686,16 @@ def intercept(self) -> Union[socket.socket, bool]: return self.client.connection def wrap_server(self) -> None: - assert self.server is not None - assert isinstance(self.server.connection, socket.socket) - self.server.wrap(text_(self.request.host), self.flags.ca_file) - assert isinstance(self.server.connection, ssl.SSLSocket) + assert self.upstream is not None + assert isinstance(self.upstream.connection, socket.socket) + self.upstream.wrap(text_(self.request.host), self.flags.ca_file) + assert isinstance(self.upstream.connection, ssl.SSLSocket) def wrap_client(self) -> None: - assert self.server is not None and self.flags.ca_signing_key_file is not None - assert isinstance(self.server.connection, ssl.SSLSocket) + assert self.upstream is not None and self.flags.ca_signing_key_file is not None + assert isinstance(self.upstream.connection, ssl.SSLSocket) generated_cert = self.generate_upstream_certificate( - cast(Dict[str, Any], self.server.connection.getpeercert()), + cast(Dict[str, Any], self.upstream.connection.getpeercert()), ) self.client.wrap(self.flags.ca_signing_key_file, generated_cert) logger.debug( @@ -723,14 +728,14 @@ def emit_request_complete(self) -> None: publisher_id=self.__class__.__name__, ) - def emit_response_events(self) -> None: + def emit_response_events(self, chunk_size: int) -> None: if not self.flags.enable_events: return if self.response.state == httpParserStates.COMPLETE: self.emit_response_complete() elif self.response.state == httpParserStates.RCVING_BODY: - self.emit_response_chunk_received() + self.emit_response_chunk_received(chunk_size) elif self.response.state == httpParserStates.HEADERS_COMPLETE: self.emit_response_headers_complete() @@ -738,10 +743,38 @@ def emit_response_headers_complete(self) -> None: if not self.flags.enable_events: return - def emit_response_chunk_received(self) -> None: + self.event_queue.publish( + request_id=self.uid.hex, + event_name=eventNames.RESPONSE_HEADERS_COMPLETE, + event_payload={ + 'headers': {text_(k): text_(v[1]) for k, v in self.response.headers.items()}, + }, + publisher_id=self.__class__.__name__, + ) + + def emit_response_chunk_received(self, chunk_size: int) -> None: if not self.flags.enable_events: return + self.event_queue.publish( + request_id=self.uid.hex, + event_name=eventNames.RESPONSE_CHUNK_RECEIVED, + event_payload={ + 'chunk_size': chunk_size, + 'encoded_chunk_size': chunk_size, + }, + publisher_id=self.__class__.__name__, + ) + def emit_response_complete(self) -> None: if not self.flags.enable_events: return + + self.event_queue.publish( + request_id=self.uid.hex, + event_name=eventNames.RESPONSE_COMPLETE, + event_payload={ + 'encoded_response_size': self.response.total_size, + }, + publisher_id=self.__class__.__name__, + ) diff --git a/tests/http/exceptions/test_http_proxy_auth_failed.py b/tests/http/exceptions/test_http_proxy_auth_failed.py index 3faff4d504..b24a87d656 100644 --- a/tests/http/exceptions/test_http_proxy_auth_failed.py +++ b/tests/http/exceptions/test_http_proxy_auth_failed.py @@ -61,7 +61,7 @@ def test_proxy_auth_fails_without_cred(self, mock_server_conn: mock.Mock) -> Non )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_not_called() self.assertEqual(self.protocol_handler.client.has_buffer(), True) self.assertEqual( @@ -90,7 +90,7 @@ def test_proxy_auth_fails_with_invalid_cred(self, mock_server_conn: mock.Mock) - )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_not_called() self.assertEqual(self.protocol_handler.client.has_buffer(), True) self.assertEqual( @@ -119,7 +119,7 @@ def test_proxy_auth_works_with_valid_cred(self, mock_server_conn: mock.Mock) -> )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_called_once() self.assertEqual(self.protocol_handler.client.has_buffer(), False) @@ -144,6 +144,6 @@ def test_proxy_auth_works_with_mixed_case_basic_string(self, mock_server_conn: m )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_called_once() self.assertEqual(self.protocol_handler.client.has_buffer(), False) diff --git a/tests/http/test_http_proxy.py b/tests/http/test_http_proxy.py index 5616b9e75f..e43bacdbbf 100644 --- a/tests/http/test_http_proxy.py +++ b/tests/http/test_http_proxy.py @@ -80,7 +80,7 @@ def test_proxy_plugin_on_and_before_upstream_connection( )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_called_with('upstream.host', DEFAULT_HTTP_PORT) self.plugin.return_value.before_upstream_connection.assert_called() self.plugin.return_value.handle_client_request.assert_called() @@ -112,7 +112,7 @@ def test_proxy_plugin_before_upstream_connection_can_teardown( )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_not_called() self.plugin.return_value.before_upstream_connection.assert_called() diff --git a/tests/http/test_http_proxy_tls_interception.py b/tests/http/test_http_proxy_tls_interception.py index bbbc6d5bb0..a413a3fe63 100644 --- a/tests/http/test_http_proxy_tls_interception.py +++ b/tests/http/test_http_proxy_tls_interception.py @@ -147,7 +147,7 @@ def mock_connection() -> Any: )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() # Assert our mocked plugins invocations self.plugin.return_value.get_descriptors.assert_called() diff --git a/tests/http/test_protocol_handler.py b/tests/http/test_protocol_handler.py index fe365e6a95..d312b8a427 100644 --- a/tests/http/test_protocol_handler.py +++ b/tests/http/test_protocol_handler.py @@ -68,7 +68,7 @@ def test_http_get(self, mock_server_connection: mock.Mock) -> None: b'GET http://localhost:%d HTTP/1.1' % self.http_server_port ) + CRLF - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.LINE_RCVD, @@ -88,15 +88,18 @@ def test_http_get(self, mock_server_connection: mock.Mock) -> None: CRLF, ]) self.assert_data_queued(mock_server_connection, server) - self.protocol_handler.run_once() + self.protocol_handler._run_once() server.flush.assert_called_once() def assert_tunnel_response( self, mock_server_connection: mock.Mock, server: mock.Mock, ) -> None: - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertTrue( - cast(HttpProxyPlugin, self.protocol_handler.plugins['HttpProxyPlugin']).server is not None, + cast( + HttpProxyPlugin, + self.protocol_handler.plugins['HttpProxyPlugin'], + ).upstream is not None, ) self.assertEqual( self.protocol_handler.client.buffer[0], @@ -180,10 +183,10 @@ def has_buffer() -> bool: self.assert_tunnel_response(mock_server_connection, server) # Dispatch tunnel established response to client - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assert_data_queued_to_server(server) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual(server.queue.call_count, 1) server.flush.assert_called_once() @@ -194,7 +197,7 @@ def test_proxy_connection_failed(self) -> None: b'Host: unknown.domain', CRLF, ]) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.client.buffer[0], ProxyConnectionFailed.RESPONSE_PKT, @@ -226,7 +229,7 @@ def test_proxy_authentication_failed( b'Host: abhinavsingh.com', CRLF, ]) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.client.buffer[0], ProxyAuthenticationFailed.RESPONSE_PKT, @@ -262,14 +265,14 @@ def test_authenticated_proxy_http_get( assert self.http_server_port is not None self._conn.recv.return_value = b'GET http://localhost:%d HTTP/1.1' % self.http_server_port - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.INITIALIZED, ) self._conn.recv.return_value = CRLF - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.LINE_RCVD, @@ -328,7 +331,7 @@ def test_authenticated_proxy_http_tunnel( self.protocol_handler.client.flush() self.assert_data_queued_to_server(server) - self.protocol_handler.run_once() + self.protocol_handler._run_once() server.flush.assert_called_once() def mock_selector_for_client_read_read_server_write( @@ -373,7 +376,7 @@ def mock_selector_for_client_read_read_server_write( def assert_data_queued( self, mock_server_connection: mock.Mock, server: mock.Mock, ) -> None: - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.COMPLETE, @@ -408,7 +411,7 @@ def assert_data_queued_to_server(self, server: mock.Mock) -> None: ]) self._conn.recv.return_value = pkt - self.protocol_handler.run_once() + self.protocol_handler._run_once() server.queue.assert_called_once_with(pkt) server.buffer_size.return_value = len(pkt) diff --git a/tests/http/test_web_server.py b/tests/http/test_web_server.py index b95bd7c671..af1eadad42 100644 --- a/tests/http/test_web_server.py +++ b/tests/http/test_web_server.py @@ -57,7 +57,7 @@ def test_pac_file_served_from_disk( self._conn = mock_fromfd.return_value self.mock_selector_for_client_read(mock_selector) self.init_and_make_pac_file_request(pac_file) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.COMPLETE, @@ -81,7 +81,7 @@ def test_pac_file_served_from_buffer( self.mock_selector_for_client_read(mock_selector) pac_file_content = b'function FindProxyForURL(url, host) { return "PROXY localhost:8899; DIRECT"; }' self.init_and_make_pac_file_request(text_(pac_file_content)) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.COMPLETE, @@ -126,7 +126,7 @@ def test_default_web_server_returns_404( b'GET /hello HTTP/1.1', CRLF, ]) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.request.state, httpParserStates.COMPLETE, @@ -194,8 +194,8 @@ def test_static_web_server_serves( ) self.protocol_handler.initialize() - self.protocol_handler.run_once() - self.protocol_handler.run_once() + self.protocol_handler._run_once() + self.protocol_handler._run_once() self.assertEqual(mock_selector.return_value.select.call_count, 2) self.assertEqual(self._conn.send.call_count, 1) @@ -258,8 +258,8 @@ def test_static_web_server_serves_404( ) self.protocol_handler.initialize() - self.protocol_handler.run_once() - self.protocol_handler.run_once() + self.protocol_handler._run_once() + self.protocol_handler._run_once() self.assertEqual(mock_selector.return_value.select.call_count, 2) self.assertEqual(self._conn.send.call_count, 1) @@ -282,7 +282,7 @@ def test_on_client_connection_called_on_teardown( ) self.protocol_handler.initialize() plugin.assert_called() - with mock.patch.object(self.protocol_handler, 'run_once') as mock_run_once: + with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once: mock_run_once.return_value = True self.protocol_handler.run() self.assertTrue(self._conn.closed) diff --git a/tests/plugin/test_http_proxy_plugins.py b/tests/plugin/test_http_proxy_plugins.py index ab62147a8d..aab0cb30a9 100644 --- a/tests/plugin/test_http_proxy_plugins.py +++ b/tests/plugin/test_http_proxy_plugins.py @@ -96,7 +96,7 @@ def test_modify_post_data_plugin( )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_called_with('httpbin.org', DEFAULT_HTTP_PORT) mock_server_conn.return_value.queue.assert_called_with( build_http_request( @@ -135,7 +135,7 @@ def test_proposed_rest_api_plugin( selectors.EVENT_READ, )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_not_called() self.assertEqual( @@ -173,7 +173,7 @@ def test_redirect_to_custom_server_plugin( selectors.EVENT_READ, )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() upstream = urlparse.urlsplit( RedirectToCustomServerPlugin.UPSTREAM_SERVER, @@ -211,7 +211,7 @@ def test_filter_by_upstream_host_plugin( selectors.EVENT_READ, )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_not_called() self.assertEqual( @@ -280,7 +280,7 @@ def closed() -> bool: ] # Client read - self.protocol_handler.run_once() + self.protocol_handler._run_once() mock_server_conn.assert_called_with('super.secure', DEFAULT_HTTP_PORT) server.connect.assert_called_once() queued_request = \ @@ -294,7 +294,7 @@ def closed() -> bool: server.queue.assert_called_once_with(queued_request) # Server write - self.protocol_handler.run_once() + self.protocol_handler._run_once() server.flush.assert_called_once() # Server read @@ -303,7 +303,7 @@ def closed() -> bool: httpStatusCodes.OK, reason=b'OK', body=b'Original Response From Upstream', ) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.client.buffer[0].tobytes(), build_http_response( @@ -334,7 +334,7 @@ def test_filter_by_url_regex_plugin( selectors.EVENT_READ, )], ] - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.client.buffer[0].tobytes(), diff --git a/tests/plugin/test_http_proxy_plugins_with_tls_interception.py b/tests/plugin/test_http_proxy_plugins_with_tls_interception.py index 164edcfee9..1f276c455d 100644 --- a/tests/plugin/test_http_proxy_plugins_with_tls_interception.py +++ b/tests/plugin/test_http_proxy_plugins_with_tls_interception.py @@ -161,7 +161,7 @@ def send(raw: bytes) -> int: self._conn.recv.return_value = build_http_request( httpMethods.CONNECT, b'uni.corn:443', ) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual(self.mock_sign_csr.call_count, 1) self.assertEqual(self.mock_gen_csr.call_count, 1) @@ -191,7 +191,7 @@ def test_modify_post_data_plugin(self) -> None: }, body=original, ) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.server.queue.assert_called_with( build_http_request( b'POST', b'/', @@ -214,11 +214,11 @@ def test_man_in_the_middle_plugin(self) -> None: self.client_ssl_connection.recv.return_value = request # Client read - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.server.queue.assert_called_once_with(request) # Server write - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.server.flush.assert_called_once() # Server read @@ -227,7 +227,7 @@ def test_man_in_the_middle_plugin(self) -> None: httpStatusCodes.OK, reason=b'OK', body=b'Original Response From Upstream', ) - self.protocol_handler.run_once() + self.protocol_handler._run_once() self.assertEqual( self.protocol_handler.client.buffer[0].tobytes(), build_http_response(