From d4edde142bd555683f7afc8dd7ed1c39e1419220 Mon Sep 17 00:00:00 2001 From: GyeongHo Kim Date: Thu, 11 Dec 2025 13:59:40 +0900 Subject: [PATCH 1/5] fix workflow files to use node v18 - Yellostone uses commander@13.1.0 and it expects node version ">=18", but lint workflow runs on node 14.21.3 - Update all actions to LTS version - Recent commits updated package-lock.json but workflow uses yarn.lock, delete yarn.lock. --- .github/workflows/lint.yml | 10 +- package.json | 3 + yarn.lock | 3556 ------------------------------------ 3 files changed, 8 insertions(+), 3561 deletions(-) delete mode 100644 yarn.lock diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b97063e..acb5a6f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,19 +17,19 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v6 with: - node-version: 14 + node-version: 18 # ESLint and Prettier must be in `package.json` - name: Install Node.js dependencies - run: yarn + run: npm ci - name: Run linters - uses: wearerequired/lint-action@v1 + uses: wearerequired/lint-action@v2 with: eslint: true prettier: true diff --git a/package.json b/package.json index b063497..5d0c779 100644 --- a/package.json +++ b/package.json @@ -34,5 +34,8 @@ "typedoc": "^0.23.25", "typedoc-plugin-markdown": "^3.14.0", "typescript": "^4.9.5" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index ab84c5d..0000000 --- a/yarn.lock +++ /dev/null @@ -1,3556 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" - integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== - -"@babel/highlight@^7.10.4": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@eslint/eslintrc@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" - integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" - integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" - integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== - -"@tsconfig/node12@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" - integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== - -"@tsconfig/node14@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" - integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== - -"@tsconfig/node16@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" - integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== - -"@types/fs-extra@^5.0.3": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" - integrity sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ== - dependencies: - "@types/node" "*" - -"@types/glob@*": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" - integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/handlebars@^4.0.38": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.1.0.tgz#3fcce9bf88f85fe73dc932240ab3fb682c624850" - integrity sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA== - dependencies: - handlebars "*" - -"@types/highlight.js@^9.12.3": - version "9.12.4" - resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.4.tgz#8c3496bd1b50cc04aeefd691140aa571d4dbfa34" - integrity sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww== - -"@types/jest@^23.3.13": - version "23.3.14" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a" - integrity sha512-Q5hTcfdudEL2yOmluA1zaSyPbzWPmJ3XfSWeP3RyoYvS9hnje1ZyagrZOuQ6+1nQC1Gw+7gap3pLNL3xL6UBug== - -"@types/json-schema@^7.0.7": - version "7.0.8" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" - integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== - -"@types/lodash@^4.14.110": - version "4.14.171" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b" - integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg== - -"@types/marked@^0.4.0": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.4.2.tgz#64a89e53ea37f61cc0f3ee1732c555c2dbf6452f" - integrity sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg== - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/minimatch@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/node@*": - version "16.0.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.1.tgz#70cedfda26af7a2ca073fdcc9beb2fff4aa693f8" - integrity sha512-hBOx4SUlEPKwRi6PrXuTGw1z6lz0fjsibcWCM378YxsSu/6+C30L6CR49zIBKHiwNWCYIcOLjg4OHKZaFeLAug== - -"@types/node@^10.12.18": - version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" - integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - -"@types/sdp-transform@^2.4.0": - version "2.4.5" - resolved "https://registry.yarnpkg.com/@types/sdp-transform/-/sdp-transform-2.4.5.tgz#3167961e0a1a5265545e278627aa37c606003f53" - integrity sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg== - -"@types/shelljs@^0.8.0": - version "0.8.9" - resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.9.tgz#45dd8501aa9882976ca3610517dac3831c2fbbf4" - integrity sha512-flVe1dvlrCyQJN/SGrnBxqHG+RzXrVKsmjD8WS/qYHpq5UPjfq7UWFBENP0ZuOl0g6OpAlL6iBoLSvKYUUmyQw== - dependencies: - "@types/glob" "*" - "@types/node" "*" - -"@typescript-eslint/eslint-plugin@^4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz#7a8320f00141666813d0ae43b49ee8244f7cf92a" - integrity sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw== - dependencies: - "@typescript-eslint/experimental-utils" "4.28.2" - "@typescript-eslint/scope-manager" "4.28.2" - debug "^4.3.1" - functional-red-black-tree "^1.0.1" - regexpp "^3.1.0" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/experimental-utils@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz#4ebdec06a10888e9326e1d51d81ad52a361bd0b0" - integrity sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.28.2" - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/typescript-estree" "4.28.2" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@^4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.2.tgz#6aff11bf4b91eb67ca7517962eede951e9e2a15d" - integrity sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w== - dependencies: - "@typescript-eslint/scope-manager" "4.28.2" - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/typescript-estree" "4.28.2" - debug "^4.3.1" - -"@typescript-eslint/scope-manager@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz#451dce90303a3ce283750111495d34c9c204e510" - integrity sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A== - dependencies: - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/visitor-keys" "4.28.2" - -"@typescript-eslint/types@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.2.tgz#e6b9e234e0e9a66c4d25bab881661e91478223b5" - integrity sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA== - -"@typescript-eslint/typescript-estree@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz#680129b2a285289a15e7c6108c84739adf3a798c" - integrity sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg== - dependencies: - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/visitor-keys" "4.28.2" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/visitor-keys@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz#bf56a400857bb68b59b311e6d0a5fbef5c3b5130" - integrity sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w== - dependencies: - "@typescript-eslint/types" "4.28.2" - eslint-visitor-keys "^2.0.0" - -abab@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" - integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4= - -abab@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -acorn-globals@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - integrity sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8= - dependencies: - acorn "^4.0.4" - -acorn-globals@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - -acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - -acorn@^4.0.4: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= - -acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== - -acorn@^6.0.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - -ajv@^8.0.1: - version "8.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.1.tgz#ae65764bf1edde8cd861281cda5057852364a295" - integrity sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - -ansi-escapes@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - integrity sha1-126/jKlNJ24keja61EpLdKthGZE= - dependencies: - default-require-extensions "^1.0.0" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@^2.1.4: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.0, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.18.0, babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-jest@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-18.0.0.tgz#17ebba8cb3285c906d859e8707e4e79795fb65e3" - integrity sha1-F+u6jLMoXJBthZ6HB+Tnl5X7ZeM= - dependencies: - babel-core "^6.0.0" - babel-plugin-istanbul "^3.0.0" - babel-preset-jest "^18.0.0" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-istanbul@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-3.1.2.tgz#11d5abde18425ec24b5d648c7e0b5d25cd354a22" - integrity sha1-EdWr3hhCXsJLXWSMfgtdJc01SiI= - dependencies: - find-up "^1.1.2" - istanbul-lib-instrument "^1.4.2" - object-assign "^4.1.0" - test-exclude "^3.3.0" - -babel-plugin-jest-hoist@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-18.0.0.tgz#4150e70ecab560e6e7344adc849498072d34e12a" - integrity sha1-QVDnDsq1YObnNErchJSYBy004So= - -babel-preset-jest@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-18.0.0.tgz#84faf8ca3ec65aba7d5e3f59bbaed935ab24049e" - integrity sha1-hPr4yj7GWrp9Xj9Zu67ZNaskBJ4= - dependencies: - babel-plugin-jest-hoist "^18.0.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.18.0, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.18.0, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browser-resolve@^1.11.2: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - -bser@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169" - integrity sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk= - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -cardinal@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" - integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU= - dependencies: - ansicolors "~0.3.2" - redeyed "~2.1.0" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - 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" - -chalk@^2.0.0, chalk@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -cli-table@^0.3.1: - version "0.3.6" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.6.tgz#e9d6aa859c7fe636981fd3787378c2a20bce92fc" - integrity sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ== - dependencies: - colors "1.0.3" - -cli-usage@^0.1.1: - version "0.1.10" - resolved "https://registry.yarnpkg.com/cli-usage/-/cli-usage-0.1.10.tgz#2c9d30a3824b48d161580a8f8d5dfe53d66b00d2" - integrity sha512-Q/s1S4Jz5LYI0LQ+XiFQCXkhMzn244ddyIffni8JIq/kL95DvQomVQ0cJC41c76hH9/FmZGY7rZB53y/bXHtRA== - dependencies: - marked "^0.7.0" - marked-terminal "^3.3.0" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -content-type-parser@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" - integrity sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ== - -convert-source-map@^1.5.1: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -"cssstyle@>= 0.2.37 < 0.3.0": - version "0.2.37" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" - integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ= - dependencies: - cssom "0.3.x" - -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== - dependencies: - cssom "0.3.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - -debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= - dependencies: - strip-bom "^2.0.0" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" - -diff@^3.0.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -errno@~0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^1.6.1, escodegen@^1.9.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-prettier@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint@^7.30.0: - version "7.30.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8" - integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.2" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1, estraverse@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.6" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a" - integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.1.tgz#5d8175aae17db61947f8b162cfc7f63264d22807" - integrity sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw== - dependencies: - reusify "^1.0.4" - -fb-watchman@^1.8.0, fb-watchman@^1.9.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.2.tgz#a24cf47827f82d38fb59a69ad70b76e3b6ae7383" - integrity sha1-okz0eCf4LTj7Waaa1wt247auc4M= - dependencies: - bser "1.0.2" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fileset@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" - integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= - dependencies: - glob "^7.0.3" - minimatch "^3.0.3" - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^1.0.0, find-up@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.1.tgz#bbef080d95fca6709362c73044a1634f7c6e7d05" - integrity sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg== - -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= - dependencies: - for-in "^1.0.1" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-extra@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.0.0, glob@^7.0.3, glob@^7.1.3: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - 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" - -globals@^13.6.0, globals@^13.9.0: - version "13.10.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.10.0.tgz#60ba56c3ac2ca845cfbf4faeca727ad9dd204676" - integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== - dependencies: - type-fest "^0.20.2" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - -globby@^11.0.3: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - -growly@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -handlebars@*, handlebars@^4.0.3, handlebars@^4.0.6: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -highlight.js@^9.13.1: - version "9.18.5" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" - integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-encoding-sniffer@^1.0.1, html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-ci@^1.0.9: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== - dependencies: - has "^1.0.3" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-api@^1.1.0-alpha.1: - version "1.3.7" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" - integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== - dependencies: - async "^2.1.4" - fileset "^2.0.2" - istanbul-lib-coverage "^1.2.1" - istanbul-lib-hook "^1.2.2" - istanbul-lib-instrument "^1.10.2" - istanbul-lib-report "^1.1.5" - istanbul-lib-source-maps "^1.2.6" - istanbul-reports "^1.5.1" - js-yaml "^3.7.0" - mkdirp "^0.5.1" - once "^1.4.0" - -istanbul-lib-coverage@^1.0.0, istanbul-lib-coverage@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" - integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== - -istanbul-lib-hook@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" - integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.10.2, istanbul-lib-instrument@^1.4.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" - integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.2.1" - semver "^5.3.0" - -istanbul-lib-report@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" - integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== - dependencies: - istanbul-lib-coverage "^1.2.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" - integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.2.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" - integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== - dependencies: - handlebars "^4.0.3" - -jest-changed-files@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-17.0.2.tgz#f5657758736996f590a51b87e5c9369d904ba7b7" - integrity sha1-9WV3WHNplvWQpRuH5ck2nZBLp7c= - -jest-cli@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-18.1.0.tgz#5ead36ecad420817c2c9baa2aa7574f63257b3d6" - integrity sha1-Xq027K1CCBfCybqiqnV09jJXs9Y= - dependencies: - ansi-escapes "^1.4.0" - callsites "^2.0.0" - chalk "^1.1.1" - graceful-fs "^4.1.6" - is-ci "^1.0.9" - istanbul-api "^1.1.0-alpha.1" - istanbul-lib-coverage "^1.0.0" - istanbul-lib-instrument "^1.1.1" - jest-changed-files "^17.0.2" - jest-config "^18.1.0" - jest-environment-jsdom "^18.1.0" - jest-file-exists "^17.0.0" - jest-haste-map "^18.1.0" - jest-jasmine2 "^18.1.0" - jest-mock "^18.0.0" - jest-resolve "^18.1.0" - jest-resolve-dependencies "^18.1.0" - jest-runtime "^18.1.0" - jest-snapshot "^18.1.0" - jest-util "^18.1.0" - json-stable-stringify "^1.0.0" - node-notifier "^4.6.1" - sane "~1.4.1" - strip-ansi "^3.0.1" - throat "^3.0.0" - which "^1.1.1" - worker-farm "^1.3.1" - yargs "^6.3.0" - -jest-config@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-18.1.0.tgz#6111740a6d48aab86ff5a9e6ab0b98bd993b6ff4" - integrity sha1-YRF0Cm1Iqrhv9anmqwuYvZk7b/Q= - dependencies: - chalk "^1.1.1" - jest-environment-jsdom "^18.1.0" - jest-environment-node "^18.1.0" - jest-jasmine2 "^18.1.0" - jest-mock "^18.0.0" - jest-resolve "^18.1.0" - jest-util "^18.1.0" - json-stable-stringify "^1.0.0" - -jest-diff@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-18.1.0.tgz#4ff79e74dd988c139195b365dc65d87f606f4803" - integrity sha1-T/eedN2YjBORlbNl3GXYf2BvSAM= - dependencies: - chalk "^1.1.3" - diff "^3.0.0" - jest-matcher-utils "^18.1.0" - pretty-format "^18.1.0" - -jest-environment-jsdom@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-18.1.0.tgz#18b42f0c4ea2bae9f36cab3639b1e8f8c384e24e" - integrity sha1-GLQvDE6iuunzbKs2ObHo+MOE4k4= - dependencies: - jest-mock "^18.0.0" - jest-util "^18.1.0" - jsdom "^9.9.1" - -jest-environment-node@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-18.1.0.tgz#4d6797572c8dda99acf5fae696eb62945547c779" - integrity sha1-TWeXVyyN2pms9frmlutilFVHx3k= - dependencies: - jest-mock "^18.0.0" - jest-util "^18.1.0" - -jest-file-exists@^17.0.0: - version "17.0.0" - resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-17.0.0.tgz#7f63eb73a1c43a13f461be261768b45af2cdd169" - integrity sha1-f2Prc6HEOhP0Yb4mF2i0WvLN0Wk= - -jest-haste-map@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-18.1.0.tgz#06839c74b770a40c1a106968851df8d281c08375" - integrity sha1-BoOcdLdwpAwaEGlohR340oHAg3U= - dependencies: - fb-watchman "^1.9.0" - graceful-fs "^4.1.6" - micromatch "^2.3.11" - sane "~1.4.1" - worker-farm "^1.3.1" - -jest-jasmine2@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-18.1.0.tgz#094e104c2c189708766c77263bb2aecb5860a80b" - integrity sha1-CU4QTCwYlwh2bHcmO7Kuy1hgqAs= - dependencies: - graceful-fs "^4.1.6" - jest-matcher-utils "^18.1.0" - jest-matchers "^18.1.0" - jest-snapshot "^18.1.0" - jest-util "^18.1.0" - -jest-matcher-utils@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-18.1.0.tgz#1ac4651955ee2a60cef1e7fcc98cdfd773c0f932" - integrity sha1-GsRlGVXuKmDO8ef8yYzf13PA+TI= - dependencies: - chalk "^1.1.3" - pretty-format "^18.1.0" - -jest-matchers@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-18.1.0.tgz#0341484bf87a1fd0bac0a4d2c899e2b77a3f1ead" - integrity sha1-A0FIS/h6H9C6wKTSyJnit3o/Hq0= - dependencies: - jest-diff "^18.1.0" - jest-matcher-utils "^18.1.0" - jest-util "^18.1.0" - pretty-format "^18.1.0" - -jest-mock@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-18.0.0.tgz#5c248846ea33fa558b526f5312ab4a6765e489b3" - integrity sha1-XCSIRuoz+lWLUm9TEqtKZ2XkibM= - -jest-resolve-dependencies@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-18.1.0.tgz#8134fb5caf59c9ed842fe0152ab01c52711f1bbb" - integrity sha1-gTT7XK9Zye2EL+AVKrAcUnEfG7s= - dependencies: - jest-file-exists "^17.0.0" - jest-resolve "^18.1.0" - -jest-resolve@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-18.1.0.tgz#6800accb536658c906cd5e29de412b1ab9ac249b" - integrity sha1-aACsy1NmWMkGzV4p3kErGrmsJJs= - dependencies: - browser-resolve "^1.11.2" - jest-file-exists "^17.0.0" - jest-haste-map "^18.1.0" - resolve "^1.2.0" - -jest-runtime@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-18.1.0.tgz#3abfd687175b21fc3b85a2b8064399e997859922" - integrity sha1-Or/WhxdbIfw7haK4BkOZ6ZeFmSI= - dependencies: - babel-core "^6.0.0" - babel-jest "^18.0.0" - babel-plugin-istanbul "^3.0.0" - chalk "^1.1.3" - graceful-fs "^4.1.6" - jest-config "^18.1.0" - jest-file-exists "^17.0.0" - jest-haste-map "^18.1.0" - jest-mock "^18.0.0" - jest-resolve "^18.1.0" - jest-snapshot "^18.1.0" - jest-util "^18.1.0" - json-stable-stringify "^1.0.0" - micromatch "^2.3.11" - yargs "^6.3.0" - -jest-snapshot@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-18.1.0.tgz#55b96d2ee639c9bce76f87f2a3fd40b71c7a5916" - integrity sha1-VbltLuY5ybznb4fyo/1Atxx6WRY= - dependencies: - jest-diff "^18.1.0" - jest-file-exists "^17.0.0" - jest-matcher-utils "^18.1.0" - jest-util "^18.1.0" - natural-compare "^1.4.0" - pretty-format "^18.1.0" - -jest-util@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-18.1.0.tgz#3a99c32114ab17f84be094382527006e6d4bfc6a" - integrity sha1-OpnDIRSrF/hL4JQ4JScAbm1L/Go= - dependencies: - chalk "^1.1.1" - diff "^3.0.0" - graceful-fs "^4.1.6" - jest-file-exists "^17.0.0" - jest-mock "^18.0.0" - mkdirp "^0.5.1" - -jest@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-18.1.0.tgz#bcebf1e203dee5c2ad2091c805300a343d9e6c7d" - integrity sha1-vOvx4gPe5cKtIJHIBTAKND2ebH0= - dependencies: - jest-cli "^18.1.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@^3.13.1, js-yaml@^3.7.0: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^11.9.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" - -jsdom@^9.9.1: - version "9.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" - integrity sha1-6MVG//ywbADUgzyoRBD+1/igl9Q= - dependencies: - abab "^1.0.3" - acorn "^4.0.4" - acorn-globals "^3.1.0" - array-equal "^1.0.0" - content-type-parser "^1.0.1" - cssom ">= 0.3.2 < 0.4.0" - cssstyle ">= 0.2.37 < 0.3.0" - escodegen "^1.6.1" - html-encoding-sniffer "^1.0.1" - nwmatcher ">= 1.3.9 < 2.0.0" - parse5 "^1.5.1" - request "^2.79.0" - sax "^1.2.1" - symbol-tree "^3.2.1" - tough-cookie "^2.3.2" - webidl-conversions "^4.0.0" - whatwg-encoding "^1.0.1" - whatwg-url "^4.3.0" - xml-name-validator "^2.0.1" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stable-stringify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -lodash._arraycopy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" - integrity sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE= - -lodash._arrayeach@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz#bab156b2a90d3f1bbd5c653403349e5e5933ef9e" - integrity sha1-urFWsqkNPxu9XGU0AzSeXlkz754= - -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._baseclone@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz#303519bf6393fe7e42f34d8b630ef7794e3542b7" - integrity sha1-MDUZv2OT/n5C802LYw73eU41Qrc= - dependencies: - lodash._arraycopy "^3.0.0" - lodash._arrayeach "^3.0.0" - lodash._baseassign "^3.0.0" - lodash._basefor "^3.0.0" - lodash.isarray "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= - -lodash._basefor@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz#7550b4e9218ef09fad24343b612021c79b4c20c2" - integrity sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI= - -lodash._bindcallback@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash.clonedeep@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz#a0a1e40d82a5ea89ff5b147b8444ed63d92827db" - integrity sha1-oKHkDYKl6on/WxR7hETtY9koJ9s= - dependencies: - lodash._baseclone "^3.0.0" - lodash._bindcallback "^3.0.0" - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash.toarray@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" - integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - -lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.4: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -marked-terminal@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-3.3.0.tgz#25ce0c0299285998c7636beaefc87055341ba1bd" - integrity sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A== - dependencies: - ansi-escapes "^3.1.0" - cardinal "^2.1.1" - chalk "^2.4.1" - cli-table "^0.3.1" - node-emoji "^1.4.1" - supports-hyperlinks "^1.0.1" - -marked@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66" - integrity sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw== - -marked@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" - integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== - -math-random@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" - integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.48.0: - version "1.48.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" - integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.31" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" - integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== - dependencies: - mime-db "1.48.0" - -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.1.1, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-emoji@^1.4.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" - integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== - dependencies: - lodash.toarray "^4.4.0" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-notifier@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-4.6.1.tgz#056d14244f3dcc1ceadfe68af9cff0c5473a33f3" - integrity sha1-BW0UJE89zBzq3+aK+c/wxUc6M/M= - dependencies: - cli-usage "^0.1.1" - growly "^1.2.0" - lodash.clonedeep "^3.0.0" - minimist "^1.1.1" - semver "^5.1.0" - shellwords "^0.1.0" - which "^1.0.5" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -"nwmatcher@>= 1.3.9 < 2.0.0": - version "1.4.4" - resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" - integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== - -nwsapi@^2.0.7: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - 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" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -parse5@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" - integrity sha1-m387DeMr543CQBsXVzzK8Pb1nZQ= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.5, path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - -prettier@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" - integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== - -pretty-format@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-18.1.0.tgz#fb65a86f7a7f9194963eee91865c1bcf1039e284" - integrity sha1-+2Wob3p/kZSWPu6RhlwbzxA54oQ= - dependencies: - ansi-styles "^2.2.1" - -private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -redeyed@~2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" - integrity sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= - dependencies: - esprima "~4.0.0" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - -regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.79.0, request@^2.87.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - 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" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.2.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^2.6.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@~1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sane/-/sane-1.4.1.tgz#88f763d74040f5f0c256b6163db399bf110ac715" - integrity sha1-iPdj10BA9fDCVrYWPbOZvxEKxxU= - dependencies: - exec-sh "^0.2.0" - fb-watchman "^1.8.0" - minimatch "^3.0.2" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.10.0" - -sax@^1.2.1, sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -sdp-transform@^2.7.0: - version "2.14.1" - resolved "https://registry.yarnpkg.com/sdp-transform/-/sdp-transform-2.14.1.tgz#2bb443583d478dee217df4caa284c46b870d5827" - integrity sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw== - -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.2.1, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shellwords@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - -source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - 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" - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.0.0, supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" - integrity sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw== - dependencies: - has-flag "^2.0.0" - supports-color "^5.0.0" - -symbol-tree@^3.2.1, symbol-tree@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - -test-exclude@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-3.3.0.tgz#7a17ca1239988c98367b0621456dbb7d4bc38977" - integrity sha1-ehfKEjmYjJg2ewYhRW27fUvDiXc= - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-3.2.0.tgz#50cb0670edbc40237b9e347d7e1f88e4620af836" - integrity sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w== - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@^2.3.2, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - dependencies: - punycode "^2.1.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -ts-node@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" - integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== - dependencies: - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -turndown@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/turndown/-/turndown-5.0.3.tgz#a1350b66155d7891f10e451432170b0f7cd7449a" - integrity sha512-popfGXEiedpq6F5saRIAThKxq/bbEPVFnsDnUdjaDGIre9f3/OL9Yi/yPbPcZ7RYUDpekghr666bBfZPrwNnhQ== - dependencies: - jsdom "^11.9.0" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -typedoc-default-themes@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" - integrity sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic= - -typedoc-plugin-markdown@^1.1.25: - version "1.2.1" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-1.2.1.tgz#919128812e82133240a316ac194ec93bbe244a35" - integrity sha512-zOjoCaCWvgVca920IDSytkGQd1sFSztNKGGWWcYq4JWqmeklOWvYy5QODIeTeAcUeYsP9FZ5Ov7BU8WJk5Ypig== - dependencies: - turndown "^5.0.3" - -typedoc@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.14.2.tgz#769f457f4f9e4bdb8b5f3b177c86b6a31d8c3dc3" - integrity sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ== - dependencies: - "@types/fs-extra" "^5.0.3" - "@types/handlebars" "^4.0.38" - "@types/highlight.js" "^9.12.3" - "@types/lodash" "^4.14.110" - "@types/marked" "^0.4.0" - "@types/minimatch" "3.0.3" - "@types/shelljs" "^0.8.0" - fs-extra "^7.0.0" - handlebars "^4.0.6" - highlight.js "^9.13.1" - lodash "^4.17.10" - marked "^0.4.0" - minimatch "^3.0.0" - progress "^2.0.0" - shelljs "^0.8.2" - typedoc-default-themes "^0.5.0" - typescript "3.2.x" - -typescript@3.2.x: - version "3.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" - integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== - -typescript@^4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== - -uglify-js@^3.1.4: - version "3.13.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d" - integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -w3c-hr-time@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -watch@~0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" - integrity sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw= - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -webidl-conversions@^4.0.0, webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^4.3.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0" - integrity sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -which@^1.0.5, which@^1.1.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -worker-farm@^1.3.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^5.2.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" - integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== - dependencies: - async-limiter "~1.0.0" - -xml-name-validator@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" - integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -y18n@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" - integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" - integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= - dependencies: - camelcase "^3.0.0" - -yargs@^6.3.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" - integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^4.2.0" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== From 9a122bb0bfd1e6413e23f1aac3e17c92b8abdb96 Mon Sep 17 00:00:00 2001 From: GyeongHo Kim Date: Thu, 11 Dec 2025 14:13:34 +0900 Subject: [PATCH 2/5] lint: add underscore on unused variables - fix lint errors(unused variables) --- .eslintrc.js => .eslintrc.cjs | 9 +++++++++ lib/transports/AACTransport.ts | 2 +- lib/transports/H264Transport.ts | 2 +- lib/transports/H265Transport.ts | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-) rename .eslintrc.js => .eslintrc.cjs (56%) diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 56% rename from .eslintrc.js rename to .eslintrc.cjs index 51bade8..561d2c4 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -7,4 +7,13 @@ module.exports = { "plugin:@typescript-eslint/recommended", "prettier", ], + rules: { + "@typescript-eslint/no-unused-vars": [ + "warn", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }, + ], + }, }; diff --git a/lib/transports/AACTransport.ts b/lib/transports/AACTransport.ts index f7c3963..24ecfd7 100644 --- a/lib/transports/AACTransport.ts +++ b/lib/transports/AACTransport.ts @@ -87,7 +87,7 @@ export default class AACTransport { // Examine the AU Header. Get the size of the AAC data const aac_frame_size = ((rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0)) >> 3; // 13 bits - const aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits + const _aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits ptr += au_headers_length; // extract the AAC block diff --git a/lib/transports/H264Transport.ts b/lib/transports/H264Transport.ts index 46270f3..67cae2e 100644 --- a/lib/transports/H264Transport.ts +++ b/lib/transports/H264Transport.ts @@ -108,7 +108,7 @@ export default class H264Transport { // Parse Fragmentation Unit Header const fu_header_s = (packet[1] >> 7) & 0x01; // start marker const fu_header_e = (packet[1] >> 6) & 0x01; // end marker - const fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0 + const _fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0 const fu_header_type = (packet[1] >> 0) & 0x1F; // Original NAL unit header // Check Start and End flags diff --git a/lib/transports/H265Transport.ts b/lib/transports/H265Transport.ts index d916e47..676c97d 100644 --- a/lib/transports/H265Transport.ts +++ b/lib/transports/H265Transport.ts @@ -94,10 +94,10 @@ export default class H265Transport { const packet = rtpPackets[i]; const payload_header = (packet[0] << 8) | (packet[1]); - const payload_header_f_bit = (payload_header >> 15) & 0x01; + const _payload_header_f_bit = (payload_header >> 15) & 0x01; const payload_header_type = (payload_header >> 9) & 0x3F; - const payload_header_layer_id = (payload_header >> 3) & 0x3F; - const payload_header_tid = payload_header & 0x7; + const _payload_header_layer_id = (payload_header >> 3) & 0x3F; + const _payload_header_tid = payload_header & 0x7; // There are three ways to Packetize NAL units into RTP Packets // Single NAL Unit Packet From 3c0c4f73e789ab59f56067d008a82f0e5a09633f Mon Sep 17 00:00:00 2001 From: GyeongHo Kim Date: Thu, 11 Dec 2025 14:14:21 +0900 Subject: [PATCH 3/5] lint: prefer const for never changed variables - fix lint error to use const variables for never changed variables --- lib/ONVIFClient.ts | 2 +- lib/RTSPClient.ts | 32 ++++++++++++++++---------------- lib/util.ts | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/ONVIFClient.ts b/lib/ONVIFClient.ts index a0f29ae..a7b996c 100644 --- a/lib/ONVIFClient.ts +++ b/lib/ONVIFClient.ts @@ -22,7 +22,7 @@ export default class ONVIFClient extends RTSPClient { } async playReverse(from?: Date, to?: Date) { - const obj: any = { + const obj: Record = { Session: this._session, 'Rate-Control': 'no', Scale: '-1.0' diff --git a/lib/RTSPClient.ts b/lib/RTSPClient.ts index 12f8a6e..cc0fd5b 100644 --- a/lib/RTSPClient.ts +++ b/lib/RTSPClient.ts @@ -162,16 +162,16 @@ export default class RTSPClient extends EventEmitter { // // Handles receiving data & closing port, called during // #connect. - _netConnect(hostname: string, port: number, secure: boolean = false): Promise { + _netConnect(hostname: string, port: number, secure = false): Promise { return new Promise((resolve, reject) => { // Set after listeners defined. - const errorListener = (err: any) => { + const errorListener = (err: Error) => { client.removeListener("error", errorListener); reject(err); }; - const postConnectErrorListener = (err: any) => { + const postConnectErrorListener = (err: Error) => { client.removeListener("error", postConnectErrorListener); this.emit("error", err); reject(err); @@ -400,8 +400,8 @@ export default class RTSPClient extends EventEmitter { const rtpPort = rtpChannel; rtpReceiver = dgram.createSocket("udp4"); - rtpReceiver.on("message", (buf, remote) => { - let packet = parseRTPPacket(buf); + rtpReceiver.on("message", (buf) => { + const packet = parseRTPPacket(buf); // Add wall clock time const detail = this.setupResult.find(item => item.rtpChannel == rtpChannel); @@ -418,7 +418,7 @@ export default class RTSPClient extends EventEmitter { // If this is a Sender Report, cache the NTP Wall Clock data if (packet.packetType == 200 && packet.senderReport != undefined) { - let detail = this.setupResult.find(item => item.rtcpChannel == rtcpChannel); + const detail = this.setupResult.find(item => item.rtcpChannel == rtcpChannel); if (detail != undefined) { detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW; detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW; @@ -820,7 +820,7 @@ export default class RTSPClient extends EventEmitter { const packetChannel = this.messageBytes[1]; if ((packetChannel & 0x01) === 0) { // even number - let packet = parseRTPPacket(this.rtspPacket); + const packet = parseRTPPacket(this.rtspPacket); // Get the Session Detail const detail = this.setupResult.find(item => item.rtpChannel == packetChannel); @@ -834,7 +834,7 @@ export default class RTSPClient extends EventEmitter { // If this is a Sender Report, cache the NTP Wall Clock data if (packet.packetType == 200 && packet.senderReport != undefined) { - let detail = this.setupResult.find(item => item.rtcpChannel == packetChannel); + const detail = this.setupResult.find(item => item.rtcpChannel == packetChannel); if (detail != undefined) { detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW; detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW; @@ -972,7 +972,7 @@ export default class RTSPClient extends EventEmitter { _sendUDPData(host: string, port: number, buffer: Buffer): void { const udp = dgram.createSocket("udp4"); - udp.send(buffer, 0, buffer.length, port, host, (err, bytes) => { + udp.send(buffer, 0, buffer.length, port, host, (_err, _bytes) => { // TODO: Don't ignore errors. udp.close(); }); @@ -997,10 +997,10 @@ export default class RTSPClient extends EventEmitter { return report; } - async _socketWrite(socket: SocketUnion, data: Buffer): Promise { + async _socketWrite(socket: SocketUnion, data: Buffer): Promise { return new Promise((resolve, reject) => { setTimeout(() => { - socket.write(data, (error: any) => { + socket.write(data, (error: Error | null) => { if (error) { reject(error); } else { @@ -1018,11 +1018,11 @@ export default class RTSPClient extends EventEmitter { // Add Wall Clock Time if (detail.sr_ntpMSW != undefined && detail.sr_ntpLSW != undefined && detail.sr_rtptimestamp != undefined && detail.mediaSource.rtp[0].rate != undefined) { - let refTimestampSecs = detail.sr_rtptimestamp / detail.mediaSource.rtp[0].rate; // H264 is 90 kHz clock rate - let packetTimestampSecs = packet.timestamp / detail.mediaSource.rtp[0].rate; // eg 90kHz - let packetTimestampDeltaSecs = packetTimestampSecs - refTimestampSecs; - let refTimestamp = new Date(this.ntpBaseDate_ms + (detail.sr_ntpMSW * 1000) + ((detail.sr_ntpLSW/Math.pow(2,32))*1000)); - let wallclockTime = new Date(refTimestamp.getTime() + (packetTimestampDeltaSecs*1000)); + const refTimestampSecs = detail.sr_rtptimestamp / detail.mediaSource.rtp[0].rate; // H264 is 90 kHz clock rate + const packetTimestampSecs = packet.timestamp / detail.mediaSource.rtp[0].rate; // eg 90kHz + const packetTimestampDeltaSecs = packetTimestampSecs - refTimestampSecs; + const refTimestamp = new Date(this.ntpBaseDate_ms + (detail.sr_ntpMSW * 1000) + ((detail.sr_ntpLSW/Math.pow(2,32))*1000)); + const wallclockTime = new Date(refTimestamp.getTime() + (packetTimestampDeltaSecs*1000)); return wallclockTime; } diff --git a/lib/util.ts b/lib/util.ts index 04b178e..eaf883b 100644 --- a/lib/util.ts +++ b/lib/util.ts @@ -85,7 +85,7 @@ export function parseRTCPPacket(buffer: Buffer): RTCPPacket { const length = buffer[2] << 8 + buffer[3]; // The length in 32 bit words (not the length in bytes) const ssrc = buffer[4] << 24 + buffer[5] << 16 + buffer[6] << 8 + buffer[7]; - let result: RTCPPacket = { + const result: RTCPPacket = { buffer, version, padding, @@ -95,7 +95,7 @@ export function parseRTCPPacket(buffer: Buffer): RTCPPacket { packetType}; if (packetType == 200) { - let senderReport: SenderReport = { + const senderReport: SenderReport = { ntpTimestampMSW: buffer.readUInt32BE(8), ntpTimestampLSW: buffer.readUInt32BE(12), rtpTimestamp: buffer.readUInt32BE(16), From fc9071495c10228483e4a0ea6f90575abab9c5ba Mon Sep 17 00:00:00 2001 From: GyeongHo Kim Date: Fri, 16 Jan 2026 14:34:25 +0900 Subject: [PATCH 4/5] lint: align code style with eslint rules and naming conventions - remove underscore prefixes from variable names - use private keyword instead of underscore prefixes for methods --- lib/ONVIFClient.ts | 4 +- lib/RTSPClient.ts | 122 ++++++++++++++++++------------------ lib/transports/RTPPacket.ts | 78 +++++++++++------------ 3 files changed, 102 insertions(+), 102 deletions(-) diff --git a/lib/ONVIFClient.ts b/lib/ONVIFClient.ts index a7b996c..2038147 100644 --- a/lib/ONVIFClient.ts +++ b/lib/ONVIFClient.ts @@ -8,7 +8,7 @@ export default class ONVIFClient extends RTSPClient { async playFrom(from: Date, to?: Date) { const obj = { - Session: this._session, + Session: this.session, Immediate: 'yes', Range: `clock=${from.toISOString()}-` }; @@ -23,7 +23,7 @@ export default class ONVIFClient extends RTSPClient { async playReverse(from?: Date, to?: Date) { const obj: Record = { - Session: this._session, + Session: this.session, 'Rate-Control': 'no', Scale: '-1.0' }; diff --git a/lib/RTSPClient.ts b/lib/RTSPClient.ts index cc0fd5b..f1e7da0 100644 --- a/lib/RTSPClient.ts +++ b/lib/RTSPClient.ts @@ -104,17 +104,17 @@ export default class RTSPClient extends EventEmitter { isConnected = false; closed = false; - // These are all set in #connect or #_netConnect. + // These are all set in #connect or #netConnect. - _url?: string; - _client?: SocketUnion; - _cSeq = 0; - _unsupportedExtensions?: string[]; + private url?: string; + private client?: SocketUnion; + private cSeq = 0; + private unsupportedExtensions?: string[]; // Example: 'SessionId'[';timeout=seconds'] - _session?: string; - _keepAliveID?: NodeJS.Timeout; - _nextFreeInterleavedChannel = 0; - _nextFreeUDPPort = 5000; + protected session?: string; // protected for ONVIFClient access + private keepAliveID?: NodeJS.Timeout; + private nextFreeInterleavedChannel = 0; + private nextFreeUDPPort = 5000; readState: ReadStates = ReadStates.SEARCHING; @@ -135,7 +135,7 @@ export default class RTSPClient extends EventEmitter { rtspPacket = Buffer.from(""); rtspPacketPointer = 0; - // Used in #_emptyReceiverReport. + // Used in emptyReceiverReport. clientSSRC = generateSSRC(); tcpSocket: SocketUnion = new net.Socket(); @@ -162,7 +162,7 @@ export default class RTSPClient extends EventEmitter { // // Handles receiving data & closing port, called during // #connect. - _netConnect(hostname: string, port: number, secure = false): Promise { + private netConnect(hostname: string, port: number, secure = false): Promise { return new Promise((resolve, reject) => { // Set after listeners defined. @@ -205,7 +205,7 @@ export default class RTSPClient extends EventEmitter { if (secure == false) { client = net.connect(port, hostname, () => { this.isConnected = true; - this._client = client; + this.client = client; client.removeListener("error", errorListener); client.on("error", postConnectErrorListener); @@ -221,7 +221,7 @@ export default class RTSPClient extends EventEmitter { client = tls.connect(port, hostname, options, () => { console.log("TLS Connection"); this.isConnected = true; - this._client = client; + this.client = client; client.removeListener("error", errorListener); @@ -230,7 +230,7 @@ export default class RTSPClient extends EventEmitter { }); } - client.on("data", this._onData.bind(this)); + client.on("data", this.onData.bind(this)); client.on("error", errorListener); client.on("close", closeListener); this.tcpSocket = client; @@ -249,14 +249,14 @@ export default class RTSPClient extends EventEmitter { secure: false } ): Promise { - const { hostname, port } = urlParse((this._url = url)); + const { hostname, port } = urlParse((this.url = url)); if (!hostname) { throw new Error("URL parsing error in connect method."); } const details: Detail[] = []; - await this._netConnect(hostname, parseInt(port || "554"), secure); + await this.netConnect(hostname, parseInt(port || "554"), secure); await this.request("OPTIONS"); const describeRes = await this.request("DESCRIBE", { @@ -376,7 +376,7 @@ export default class RTSPClient extends EventEmitter { streamurl = mediaSource.control; } else { // relative path - streamurl = this._url + "/" + mediaSource.control; + streamurl = this.url + "/" + mediaSource.control; } } @@ -393,9 +393,9 @@ export default class RTSPClient extends EventEmitter { // Create a pair of UDP listeners, even numbered port for RTP // and odd numbered port for RTCP - rtpChannel = this._nextFreeUDPPort; - rtcpChannel = this._nextFreeUDPPort + 1; - this._nextFreeUDPPort += 2; + rtpChannel = this.nextFreeUDPPort; + rtcpChannel = this.nextFreeUDPPort + 1; + this.nextFreeUDPPort += 2; const rtpPort = rtpChannel; rtpReceiver = dgram.createSocket("udp4"); @@ -428,8 +428,8 @@ export default class RTSPClient extends EventEmitter { this.emit("controlData", rtcpPort, packet); - const receiver_report = this._emptyReceiverReport(); - this._sendUDPData(remote.address, remote.port, receiver_report); + const receiver_report = this.emptyReceiverReport(); + this.sendUDPData(remote.address, remote.port, receiver_report); }); // Block until both UDP sockets are open. @@ -445,22 +445,22 @@ export default class RTSPClient extends EventEmitter { const setupHeader = { Transport: `RTP/AVP;unicast;client_port=${rtpPort}-${rtcpPort}`, }; - if (this._session) - Object.assign(setupHeader, { Session: this._session }); + if (this.session) + Object.assign(setupHeader, { Session: this.session }); setupRes = await this.request("SETUP", setupHeader, streamurl); } else if (connection === "tcp") { // channel 0, RTP // channel 1, RTCP - rtpChannel = this._nextFreeInterleavedChannel; - rtcpChannel = this._nextFreeInterleavedChannel + 1; - this._nextFreeInterleavedChannel += 2; + rtpChannel = this.nextFreeInterleavedChannel; + rtcpChannel = this.nextFreeInterleavedChannel + 1; + this.nextFreeInterleavedChannel += 2; const setupHeader = { Transport: `RTP/AVP/TCP;interleaved=${rtpChannel}-${rtcpChannel}`, }; - if (this._session) - Object.assign(setupHeader, { Session: this._session }); // not used on first SETUP + if (this.session) + Object.assign(setupHeader, { Session: this.session }); // not used on first SETUP setupRes = await this.request("SETUP", setupHeader, streamurl); } else { throw new Error( @@ -503,11 +503,11 @@ export default class RTSPClient extends EventEmitter { } if (headers.Unsupported) { - this._unsupportedExtensions = headers.Unsupported.split(","); + this.unsupportedExtensions = headers.Unsupported.split(","); } if (headers.Session) { - this._session = headers.Session.split(";")[0]; + this.session = headers.Session.split(";")[0]; } const detail: Detail = { @@ -526,8 +526,8 @@ export default class RTSPClient extends EventEmitter { if (keepAlive) { // Start a Timer to send OPTIONS every 20 seconds to keep stream alive // using the Session ID - this._keepAliveID = setInterval(() => { - this.request("OPTIONS", { Session: this._session }); + this.keepAliveID = setInterval(() => { + this.request("OPTIONS", { Session: this.session }); // this.request("OPTIONS"); }, 20 * 1000); } @@ -541,13 +541,13 @@ export default class RTSPClient extends EventEmitter { headersParam: Headers = {}, url?: string ): Promise<{ headers: Headers; mediaHeaders?: string[] } | void> { - if (!this._client) { + if (!this.client) { return Promise.resolve(); } - const id = ++this._cSeq; + const id = ++this.cSeq; // mutable via string addition - let req = `${requestName} ${url || this._url} RTSP/1.0\r\nCSeq: ${id}\r\n`; + let req = `${requestName} ${url || this.url} RTSP/1.0\r\nCSeq: ${id}\r\n`; const headers = { ...this.headers, @@ -565,7 +565,7 @@ export default class RTSPClient extends EventEmitter { this.emit("log", req, "C->S"); // Make sure to add an empty line after the request. - this._client.write(`${req}\r\n`); + this.client.write(`${req}\r\n`); return new Promise((resolve, reject) => { const responseHandler = ( @@ -641,14 +641,14 @@ export default class RTSPClient extends EventEmitter { const ha1 = HashFunction( `${this.username}:${realm}:${this.password}` ); - const ha2 = HashFunction(`${requestName}:${this._url}`); + const ha2 = HashFunction(`${requestName}:${this.url}`); const ha3 = HashFunction(`${ha1}:${nonce}:${ha2}`); // Some RTSP servers to not accept "algorithm=NNN" in the authString and reject the authentication. So only add algorithm=ZZZZ when not using MD5 if (algorithm == "MD5") - authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",uri="${this._url}",response="${ha3}"`; + authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",uri="${this.url}",response="${ha3}"`; else - authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",algorithm=${algorithm},uri="${this._url}",response="${ha3}"`; + authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",algorithm=${algorithm},uri="${this.url}",response="${ha3}"`; } else if (type === "Basic") { // Basic Authentication // https://xkcd.com/538/ @@ -676,7 +676,7 @@ export default class RTSPClient extends EventEmitter { } respond(status: string, headersParam: Headers = {}): void { - if (!this._client) { + if (!this.client) { return; } @@ -693,7 +693,7 @@ export default class RTSPClient extends EventEmitter { .join(""); this.emit("log", res, "C->S"); - this._client.write(`${res}\r\n`); + this.client.write(`${res}\r\n`); } async play(): Promise { @@ -701,7 +701,7 @@ export default class RTSPClient extends EventEmitter { throw new Error("Client is not connected."); } - await this.request("PLAY", { Session: this._session }); + await this.request("PLAY", { Session: this.session }); } async pause(): Promise { @@ -709,7 +709,7 @@ export default class RTSPClient extends EventEmitter { throw new Error("Client is not connected."); } - await this.request("PAUSE", { Session: this._session }); + await this.request("PAUSE", { Session: this.session }); } async sendAudioBackChannel(audioChunk: Buffer): Promise { @@ -744,7 +744,7 @@ export default class RTSPClient extends EventEmitter { interleavedHeader = Buffer.concat([interleavedHeader, Buffer.from([channelInterleaved])]); interleavedHeader = Buffer.concat([interleavedHeader, bufferLength]); const dataToSend = Buffer.concat([interleavedHeader, rtp.packet]); - await this._socketWrite(this.tcpSocket, dataToSend); + await this.socketWrite(this.tcpSocket, dataToSend); } return; } @@ -753,29 +753,29 @@ export default class RTSPClient extends EventEmitter { if (this.closed) return; this.closed = true; - if (!this._client) { + if (!this.client) { return; } if (!isImmediate) { await this.request("TEARDOWN", { - Session: this._session, + Session: this.session, }); } - this._client.end(); + this.client.end(); this.removeAllListeners("response"); - if (this._keepAliveID != undefined) { - clearInterval(this._keepAliveID); - this._keepAliveID = undefined; + if (this.keepAliveID != undefined) { + clearInterval(this.keepAliveID); + this.keepAliveID = undefined; } this.isConnected = false; - this._cSeq = 0; + this.cSeq = 0; } - _onData(data: Buffer): void { + private onData(data: Buffer): void { let index = 0; // $ @@ -844,8 +844,8 @@ export default class RTSPClient extends EventEmitter { this.emit("controlData", packetChannel, packet); - const receiver_report = this._emptyReceiverReport(); - this._sendInterleavedData(packetChannel, receiver_report); + const receiver_report = this.emptyReceiverReport(); + this.sendInterleavedData(packetChannel, receiver_report); } this.readState = ReadStates.SEARCHING; } @@ -952,8 +952,8 @@ export default class RTSPClient extends EventEmitter { } // end while } - _sendInterleavedData(channel: number, buffer: Buffer): void { - if (!this._client) { + private sendInterleavedData(channel: number, buffer: Buffer): void { + if (!this.client) { return; } @@ -967,10 +967,10 @@ export default class RTSPClient extends EventEmitter { header[3] = (buffer.length >> 0) & 0xff; const data = Buffer.concat([header, buffer]); - this._client.write(data); + this.client.write(data); } - _sendUDPData(host: string, port: number, buffer: Buffer): void { + private sendUDPData(host: string, port: number, buffer: Buffer): void { const udp = dgram.createSocket("udp4"); udp.send(buffer, 0, buffer.length, port, host, (_err, _bytes) => { // TODO: Don't ignore errors. @@ -978,7 +978,7 @@ export default class RTSPClient extends EventEmitter { }); } - _emptyReceiverReport(): Buffer { + private emptyReceiverReport(): Buffer { const report = Buffer.alloc(8); const version = 2; const paddingBit = 0; @@ -997,7 +997,7 @@ export default class RTSPClient extends EventEmitter { return report; } - async _socketWrite(socket: SocketUnion, data: Buffer): Promise { + private async socketWrite(socket: SocketUnion, data: Buffer): Promise { return new Promise((resolve, reject) => { setTimeout(() => { socket.write(data, (error: Error | null) => { diff --git a/lib/transports/RTPPacket.ts b/lib/transports/RTPPacket.ts index 66f2754..8b071d1 100644 --- a/lib/transports/RTPPacket.ts +++ b/lib/transports/RTPPacket.ts @@ -8,7 +8,7 @@ function toUnsigned(val: number): number { } class RTPPacket { - private _bufpkt: Buffer; // holds the RTP header (12 bytes) AND the RTP packet payload + private bufpkt: Buffer; // holds the RTP header (12 bytes) AND the RTP packet payload constructor(bufpayload: Buffer, hasHeader = false) { /* See RFC3550 for more details: http://www.ietf.org/rfc/rfc3550.txt @@ -27,7 +27,7 @@ class RTPPacket { */ if (hasHeader && bufpayload.length >= 12) { // full packet (generally an incoming packet straight from the socket) - this._bufpkt = bufpayload; + this.bufpkt = bufpayload; /*V = (bufpkt[0] >>> 6 & 0x03); P = (bufpkt[0] >>> 5 & 0x01); X = (bufpkt[0] >>> 4 & 0x01); @@ -40,7 +40,7 @@ class RTPPacket { // bufpkt[12..bufpkg.length-1] == payload data } else { // just payload data (for outgoing/sending) - this._bufpkt = Buffer.alloc(12 + bufpayload.length); // V..SSRC + payload + this.bufpkt = Buffer.alloc(12 + bufpayload.length); // V..SSRC + payload /*bufpkt[0] = (V << 6 | P << 5 | X << 4 | CC); bufpkt[1] = (M << 7 | PT); bufpkt[2] = (SN >>> 8) @@ -53,83 +53,83 @@ class RTPPacket { bufpkt[9] = (SSRC >>> 16 & 0xFF); bufpkt[10] = (SSRC >>> 8 & 0xFF); bufpkt[11] = (SSRC & 0xFF);*/ - this._bufpkt[0] = 0x80; - this._bufpkt[1] = 0; + this.bufpkt[0] = 0x80; + this.bufpkt[1] = 0; const SN = Math.floor(1000 * Math.random()); - this._bufpkt[2] = (SN >>> 8) - this._bufpkt[3] = (SN & 0xFF); - this._bufpkt[4] = 0; - this._bufpkt[5] = 0; - this._bufpkt[6] = 0; - this._bufpkt[7] = 1; - this._bufpkt[8] = 0; - this._bufpkt[9] = 0; - this._bufpkt[10] = 0; - this._bufpkt[11] = 1; - bufpayload.copy(this._bufpkt, 12, 0); // append payload data + this.bufpkt[2] = (SN >>> 8) + this.bufpkt[3] = (SN & 0xFF); + this.bufpkt[4] = 0; + this.bufpkt[5] = 0; + this.bufpkt[6] = 0; + this.bufpkt[7] = 1; + this.bufpkt[8] = 0; + this.bufpkt[9] = 0; + this.bufpkt[10] = 0; + this.bufpkt[11] = 1; + bufpayload.copy(this.bufpkt, 12, 0); // append payload data } } - public get type() { return (this._bufpkt[1] & 0x7F); } + public get type() { return (this.bufpkt[1] & 0x7F); } public set type(val) { val = toUnsigned(val); if (val <= 127) { - this._bufpkt[1] -= (this._bufpkt[1] & 0x7F); - this._bufpkt[1] |= val; + this.bufpkt[1] -= (this.bufpkt[1] & 0x7F); + this.bufpkt[1] |= val; } } - public get seq() { return (this._bufpkt[2] << 8 | this._bufpkt[3]); } + public get seq() { return (this.bufpkt[2] << 8 | this.bufpkt[3]); } public set seq(val) { val = toUnsigned(val); if (val <= 65535) { - this._bufpkt[2] = (val >>> 8); - this._bufpkt[3] = (val & 0xFF); + this.bufpkt[2] = (val >>> 8); + this.bufpkt[3] = (val & 0xFF); } } - public get time() { return (this._bufpkt[4] << 24 | this._bufpkt[5] << 16 | this._bufpkt[6] << 8 | this._bufpkt[7]); } + public get time() { return (this.bufpkt[4] << 24 | this.bufpkt[5] << 16 | this.bufpkt[6] << 8 | this.bufpkt[7]); } public set time(val) { val = toUnsigned(val); if (val <= 4294967295) { - this._bufpkt[4] = (val >>> 24); - this._bufpkt[5] = (val >>> 16 & 0xFF); - this._bufpkt[6] = (val >>> 8 & 0xFF); - this._bufpkt[7] = (val & 0xFF); + this.bufpkt[4] = (val >>> 24); + this.bufpkt[5] = (val >>> 16 & 0xFF); + this.bufpkt[6] = (val >>> 8 & 0xFF); + this.bufpkt[7] = (val & 0xFF); } } - public get source() { return (this._bufpkt[8] << 24 | this._bufpkt[9] << 16 | this._bufpkt[10] << 8 | this._bufpkt[11]); } + public get source() { return (this.bufpkt[8] << 24 | this.bufpkt[9] << 16 | this.bufpkt[10] << 8 | this.bufpkt[11]); } public set source(val) { val = toUnsigned(val); if (val <= 4294967295) { - this._bufpkt[8] = (val >>> 24); - this._bufpkt[9] = (val >>> 16 & 0xFF); - this._bufpkt[10] = (val >>> 8 & 0xFF); - this._bufpkt[11] = (val & 0xFF); + this.bufpkt[8] = (val >>> 24); + this.bufpkt[9] = (val >>> 16 & 0xFF); + this.bufpkt[10] = (val >>> 8 & 0xFF); + this.bufpkt[11] = (val & 0xFF); } } // Gets/Sets the payload of an existing RTP packet (without any RTP Headers) - public get payload() { return (this._bufpkt.slice(12, this._bufpkt.length)); } + public get payload() { return (this.bufpkt.slice(12, this.bufpkt.length)); } public set payload(val) { if (Buffer.isBuffer(val)) { const newsize = 12 + val.length; - if (this._bufpkt.length == newsize) - val.copy(this._bufpkt, 12, 0); + if (this.bufpkt.length == newsize) + val.copy(this.bufpkt, 12, 0); else { const newbuf = Buffer.alloc(newsize); - this._bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header + this.bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header val.copy(newbuf, 12, 0); - this._bufpkt = newbuf; + this.bufpkt = newbuf; } } } // gets/sets the RTP Header and RTP Payload - public get packet() { return this._bufpkt; } + public get packet() { return this.bufpkt; } public set packet(val) { - this._bufpkt = val; + this.bufpkt = val; } } From 6d48a28697e091abab721caf9ffe0e56f37120c4 Mon Sep 17 00:00:00 2001 From: GyeongHo Kim Date: Thu, 11 Dec 2025 14:16:51 +0900 Subject: [PATCH 5/5] update dist to latest src --- dist/ONVIFClient.js | 4 +- dist/ONVIFClient.js.map | 2 +- dist/RTSPClient.d.ts | 28 +-- dist/RTSPClient.js | 147 ++++++++------- dist/RTSPClient.js.map | 2 +- dist/index.d.ts | 3 +- dist/index.js | 4 +- dist/index.js.map | 2 +- dist/transports/AACTransport.js | 2 +- dist/transports/AACTransport.js.map | 2 +- dist/transports/AV1Transport.d.ts | 24 +++ dist/transports/AV1Transport.js | 264 +++++++++++++++++++++++++++ dist/transports/AV1Transport.js.map | 1 + dist/transports/H264Transport.js | 2 +- dist/transports/H264Transport.js.map | 2 +- dist/transports/H265Transport.js | 6 +- dist/transports/H265Transport.js.map | 2 +- dist/transports/RTPPacket.d.ts | 2 +- dist/transports/RTPPacket.js | 76 ++++---- dist/transports/RTPPacket.js.map | 2 +- dist/util.js | 4 +- dist/util.js.map | 2 +- package-lock.json | 3 + 23 files changed, 445 insertions(+), 141 deletions(-) create mode 100644 dist/transports/AV1Transport.d.ts create mode 100644 dist/transports/AV1Transport.js create mode 100644 dist/transports/AV1Transport.js.map diff --git a/dist/ONVIFClient.js b/dist/ONVIFClient.js index b99b120..669f6af 100644 --- a/dist/ONVIFClient.js +++ b/dist/ONVIFClient.js @@ -8,7 +8,7 @@ class ONVIFClient extends RTSPClient_1.default { } async playFrom(from, to) { const obj = { - Session: this._session, + Session: this.session, Immediate: 'yes', Range: `clock=${from.toISOString()}-` }; @@ -20,7 +20,7 @@ class ONVIFClient extends RTSPClient_1.default { } async playReverse(from, to) { const obj = { - Session: this._session, + Session: this.session, 'Rate-Control': 'no', Scale: '-1.0' }; diff --git a/dist/ONVIFClient.js.map b/dist/ONVIFClient.js.map index cdca415..4888efa 100644 --- a/dist/ONVIFClient.js.map +++ b/dist/ONVIFClient.js.map @@ -1 +1 @@ -{"version":3,"file":"ONVIFClient.js","sourceRoot":"","sources":["../lib/ONVIFClient.ts"],"names":[],"mappings":";;AAAA,6CAAsC;AAEtC,qCAAqC;AACrC,MAAqB,WAAY,SAAQ,oBAAU;IACjD,YAAY,QAAgB,EAAE,QAAgB;QAC5C,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAU,EAAE,EAAS;QAClC,MAAM,GAAG,GAAG;YACV,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,SAAS,IAAI,CAAC,WAAW,EAAE,GAAG;SACtC,CAAC;QAEF,IAAI,EAAE,EAAE;YACN,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAC/B;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAW,EAAE,EAAS;QACtC,MAAM,GAAG,GAAQ;YACf,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,cAAc,EAAE,IAAI;YACpB,KAAK,EAAE,MAAM;SACd,CAAC;QAEF,IAAI,IAAI,EAAE;YACR,GAAG,CAAC,KAAK,GAAG,SAAS,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC;YAC3C,IAAI,EAAE,EAAE;gBACN,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;aAC/B;SACF;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AArCD,8BAqCC","sourcesContent":["import RTSPClient from \"./RTSPClient\";\n\n// RTSP client with ONVIF extensions.\nexport default class ONVIFClient extends RTSPClient {\n constructor(username: string, password: string) {\n super(username, password, { Require: \"onvif-replay\" });\n }\n\n async playFrom(from: Date, to?: Date) {\n const obj = {\n Session: this._session,\n Immediate: 'yes',\n Range: `clock=${from.toISOString()}-`\n };\n\n if (to) {\n obj.Range += to.toISOString();\n }\n\n await this.request(\"PLAY\", obj);\n return this;\n }\n\n async playReverse(from?: Date, to?: Date) {\n const obj: any = {\n Session: this._session,\n 'Rate-Control': 'no',\n Scale: '-1.0'\n };\n\n if (from) {\n obj.Range = `clock=${from.toISOString()}-`;\n if (to) {\n obj.Range += to.toISOString();\n }\n }\n\n await this.request(\"PLAY\", obj);\n return this;\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"ONVIFClient.js","sourceRoot":"","sources":["../lib/ONVIFClient.ts"],"names":[],"mappings":";;AAAA,6CAAsC;AAEtC,qCAAqC;AACrC,MAAqB,WAAY,SAAQ,oBAAU;IACjD,YAAY,QAAgB,EAAE,QAAgB;QAC5C,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAU,EAAE,EAAS;QAClC,MAAM,GAAG,GAAG;YACV,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,SAAS,IAAI,CAAC,WAAW,EAAE,GAAG;SACtC,CAAC;QAEF,IAAI,EAAE,EAAE;YACN,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAC/B;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAW,EAAE,EAAS;QACtC,MAAM,GAAG,GAAuC;YAC9C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,cAAc,EAAE,IAAI;YACpB,KAAK,EAAE,MAAM;SACd,CAAC;QAEF,IAAI,IAAI,EAAE;YACR,GAAG,CAAC,KAAK,GAAG,SAAS,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC;YAC3C,IAAI,EAAE,EAAE;gBACN,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;aAC/B;SACF;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AArCD,8BAqCC","sourcesContent":["import RTSPClient from \"./RTSPClient\";\r\n\r\n// RTSP client with ONVIF extensions.\r\nexport default class ONVIFClient extends RTSPClient {\r\n constructor(username: string, password: string) {\r\n super(username, password, { Require: \"onvif-replay\" });\r\n }\r\n\r\n async playFrom(from: Date, to?: Date) {\r\n const obj = {\r\n Session: this.session,\r\n Immediate: 'yes',\r\n Range: `clock=${from.toISOString()}-`\r\n };\r\n\r\n if (to) {\r\n obj.Range += to.toISOString();\r\n }\r\n\r\n await this.request(\"PLAY\", obj);\r\n return this;\r\n }\r\n\r\n async playReverse(from?: Date, to?: Date) {\r\n const obj: Record = {\r\n Session: this.session,\r\n 'Rate-Control': 'no',\r\n Scale: '-1.0'\r\n };\r\n\r\n if (from) {\r\n obj.Range = `clock=${from.toISOString()}-`;\r\n if (to) {\r\n obj.Range += to.toISOString();\r\n }\r\n }\r\n\r\n await this.request(\"PLAY\", obj);\r\n return this;\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/RTSPClient.d.ts b/dist/RTSPClient.d.ts index 7690b7b..3cbfd40 100644 --- a/dist/RTSPClient.d.ts +++ b/dist/RTSPClient.d.ts @@ -50,14 +50,14 @@ export default class RTSPClient extends EventEmitter { }; isConnected: boolean; closed: boolean; - _url?: string; - _client?: SocketUnion; - _cSeq: number; - _unsupportedExtensions?: string[]; - _session?: string; - _keepAliveID?: NodeJS.Timeout; - _nextFreeInterleavedChannel: number; - _nextFreeUDPPort: number; + private url?; + private client?; + private cSeq; + private unsupportedExtensions?; + protected session?: string; + private keepAliveID?; + private nextFreeInterleavedChannel; + private nextFreeUDPPort; readState: ReadStates; messageBytes: number[]; rtspContentLength: number; @@ -72,7 +72,7 @@ export default class RTSPClient extends EventEmitter { constructor(username: string, password: string, headers?: { [key: string]: string; }); - _netConnect(hostname: string, port: number, secure?: boolean): Promise; + private netConnect; connect(url: string, { keepAlive, connection, secure, }?: { keepAlive: boolean; connection?: Connection; @@ -87,11 +87,11 @@ export default class RTSPClient extends EventEmitter { pause(): Promise; sendAudioBackChannel(audioChunk: Buffer): Promise; close(isImmediate?: boolean): Promise; - _onData(data: Buffer): void; - _sendInterleavedData(channel: number, buffer: Buffer): void; - _sendUDPData(host: string, port: number, buffer: Buffer): void; - _emptyReceiverReport(): Buffer; - _socketWrite(socket: SocketUnion, data: Buffer): Promise; + private onData; + private sendInterleavedData; + private sendUDPData; + private emptyReceiverReport; + private socketWrite; ntpBaseDate_ms: number; GetWallClockTime(packet: util.RTPPacket, detail: Detail): Date | undefined; } diff --git a/dist/RTSPClient.js b/dist/RTSPClient.js index d2ae05c..3f80307 100644 --- a/dist/RTSPClient.js +++ b/dist/RTSPClient.js @@ -9,6 +9,7 @@ const util_1 = require("./util"); const transform = require("sdp-transform"); const RTPPacket_1 = require("./transports/RTPPacket"); const RTP_AVP = "RTP/AVP"; +const RTP_AVPF = "RTP/AVPF"; // Used by AV1. This is RTP with Feedback (via RTCP) to request Keyframes via RTCP const STATUS_OK = 200; const STATUS_UNAUTH = 401; // The WWW_AUTH is of the format @@ -48,9 +49,9 @@ class RTSPClient extends events_1.EventEmitter { super(); this.isConnected = false; this.closed = false; - this._cSeq = 0; - this._nextFreeInterleavedChannel = 0; - this._nextFreeUDPPort = 5000; + this.cSeq = 0; + this.nextFreeInterleavedChannel = 0; + this.nextFreeUDPPort = 5000; this.readState = ReadStates.SEARCHING; // Used as a cache for the data stream. // What's in here is based on current #readState. @@ -64,7 +65,7 @@ class RTSPClient extends events_1.EventEmitter { this.rtspPacketLength = 0; this.rtspPacket = Buffer.from(""); this.rtspPacketPointer = 0; - // Used in #_emptyReceiverReport. + // Used in emptyReceiverReport. this.clientSSRC = (0, util_1.generateSSRC)(); this.tcpSocket = new net.Socket(); this.setupResult = []; @@ -80,7 +81,7 @@ class RTSPClient extends events_1.EventEmitter { // // Handles receiving data & closing port, called during // #connect. - _netConnect(hostname, port, secure = false) { + netConnect(hostname, port, secure = false) { return new Promise((resolve, reject) => { // Set after listeners defined. const errorListener = (err) => { @@ -115,7 +116,7 @@ class RTSPClient extends events_1.EventEmitter { if (secure == false) { client = net.connect(port, hostname, () => { this.isConnected = true; - this._client = client; + this.client = client; client.removeListener("error", errorListener); client.on("error", postConnectErrorListener); this.on("response", responseListener); @@ -129,15 +130,13 @@ class RTSPClient extends events_1.EventEmitter { client = tls.connect(port, hostname, options, () => { console.log("TLS Connection"); this.isConnected = true; - this._client = client; + this.client = client; client.removeListener("error", errorListener); - client.on("error", postConnectErrorListener); this.on("response", responseListener); resolve(this); }); } - - client.on("data", this._onData.bind(this)); + client.on("data", this.onData.bind(this)); client.on("error", errorListener); client.on("close", closeListener); this.tcpSocket = client; @@ -148,12 +147,12 @@ class RTSPClient extends events_1.EventEmitter { connection: "udp", secure: false }) { - const { hostname, port } = (0, url_1.parse)((this._url = url)); + const { hostname, port } = (0, url_1.parse)((this.url = url)); if (!hostname) { throw new Error("URL parsing error in connect method."); } const details = []; - await this._netConnect(hostname, parseInt(port || "554"), secure); + await this.netConnect(hostname, parseInt(port || "554"), secure); await this.request("OPTIONS"); const describeRes = await this.request("DESCRIBE", { Accept: "application/sdp", @@ -161,7 +160,7 @@ class RTSPClient extends events_1.EventEmitter { if (!describeRes || !describeRes.mediaHeaders) { throw new Error("No media headers on DESCRIBE; RTSP server is broken (sanity check)"); } - // For now, only RTP/AVP is supported. (Some RTSPS servers use RTP/SAVP) + // For now, only RTP/AVP and RTP/AVPF are supported. (Some RTSPS servers use RTP/SAVP) const { media } = transform.parse(describeRes.mediaHeaders.join("\r\n")); // Loop over the Media Streams in the SDP looking for Video or Audio // In theory the SDP can contain multiple Video and Audio Streams. We only want one of each type @@ -197,6 +196,16 @@ class RTSPClient extends events_1.EventEmitter { codec = "H265"; } } + if (mediaSource.type === "video" && + (mediaSource.protocol === RTP_AVP || mediaSource.protocol === RTP_AVPF) && + mediaSource.rtp[0].codec === "AV1") { + this.emit("log", "AV1 Video Stream Found in SDP", ""); + if (hasVideo == false) { + needSetup = true; + hasVideo = true; + codec = "AV1"; + } + } if (mediaSource.type === "audio" && (mediaSource.direction === "recvonly" || mediaSource.direction === "sendrecv") && mediaSource.protocol === RTP_AVP && @@ -239,7 +248,7 @@ class RTSPClient extends events_1.EventEmitter { } else { // relative path - streamurl = this._url + "/" + mediaSource.control; + streamurl = this.url + "/" + mediaSource.control; } } // Perform a SETUP on the streamurl @@ -253,13 +262,13 @@ class RTSPClient extends events_1.EventEmitter { if (connection === "udp") { // Create a pair of UDP listeners, even numbered port for RTP // and odd numbered port for RTCP - rtpChannel = this._nextFreeUDPPort; - rtcpChannel = this._nextFreeUDPPort + 1; - this._nextFreeUDPPort += 2; + rtpChannel = this.nextFreeUDPPort; + rtcpChannel = this.nextFreeUDPPort + 1; + this.nextFreeUDPPort += 2; const rtpPort = rtpChannel; rtpReceiver = dgram.createSocket("udp4"); - rtpReceiver.on("message", (buf, remote) => { - let packet = (0, util_1.parseRTPPacket)(buf); + rtpReceiver.on("message", (buf) => { + const packet = (0, util_1.parseRTPPacket)(buf); // Add wall clock time const detail = this.setupResult.find(item => item.rtpChannel == rtpChannel); if (detail != undefined) @@ -272,7 +281,7 @@ class RTSPClient extends events_1.EventEmitter { const packet = (0, util_1.parseRTCPPacket)(buf); // If this is a Sender Report, cache the NTP Wall Clock data if (packet.packetType == 200 && packet.senderReport != undefined) { - let detail = this.setupResult.find(item => item.rtcpChannel == rtcpChannel); + const detail = this.setupResult.find(item => item.rtcpChannel == rtcpChannel); if (detail != undefined) { detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW; detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW; @@ -280,8 +289,8 @@ class RTSPClient extends events_1.EventEmitter { } } this.emit("controlData", rtcpPort, packet); - const receiver_report = this._emptyReceiverReport(); - this._sendUDPData(remote.address, remote.port, receiver_report); + const receiver_report = this.emptyReceiverReport(); + this.sendUDPData(remote.address, remote.port, receiver_report); }); // Block until both UDP sockets are open. await new Promise((resolve) => { @@ -293,21 +302,21 @@ class RTSPClient extends events_1.EventEmitter { const setupHeader = { Transport: `RTP/AVP;unicast;client_port=${rtpPort}-${rtcpPort}`, }; - if (this._session) - Object.assign(setupHeader, { Session: this._session }); + if (this.session) + Object.assign(setupHeader, { Session: this.session }); setupRes = await this.request("SETUP", setupHeader, streamurl); } else if (connection === "tcp") { // channel 0, RTP // channel 1, RTCP - rtpChannel = this._nextFreeInterleavedChannel; - rtcpChannel = this._nextFreeInterleavedChannel + 1; - this._nextFreeInterleavedChannel += 2; + rtpChannel = this.nextFreeInterleavedChannel; + rtcpChannel = this.nextFreeInterleavedChannel + 1; + this.nextFreeInterleavedChannel += 2; const setupHeader = { Transport: `RTP/AVP/TCP;interleaved=${rtpChannel}-${rtcpChannel}`, }; - if (this._session) - Object.assign(setupHeader, { Session: this._session }); // not used on first SETUP + if (this.session) + Object.assign(setupHeader, { Session: this.session }); // not used on first SETUP setupRes = await this.request("SETUP", setupHeader, streamurl); } else { @@ -335,10 +344,10 @@ class RTSPClient extends events_1.EventEmitter { rtcpReceiver.send(Buffer.from(''), Number(transport.parameters["server_port"].split("-")[1]), hostname); } if (headers.Unsupported) { - this._unsupportedExtensions = headers.Unsupported.split(","); + this.unsupportedExtensions = headers.Unsupported.split(","); } if (headers.Session) { - this._session = headers.Session.split(";")[0]; + this.session = headers.Session.split(";")[0]; } const detail = { codec, @@ -354,8 +363,8 @@ class RTSPClient extends events_1.EventEmitter { if (keepAlive) { // Start a Timer to send OPTIONS every 20 seconds to keep stream alive // using the Session ID - this._keepAliveID = setInterval(() => { - this.request("OPTIONS", { Session: this._session }); + this.keepAliveID = setInterval(() => { + this.request("OPTIONS", { Session: this.session }); // this.request("OPTIONS"); }, 20 * 1000); } @@ -363,12 +372,12 @@ class RTSPClient extends events_1.EventEmitter { return details; } request(requestName, headersParam = {}, url) { - if (!this._client) { + if (!this.client) { return Promise.resolve(); } - const id = ++this._cSeq; + const id = ++this.cSeq; // mutable via string addition - let req = `${requestName} ${url || this._url} RTSP/1.0\r\nCSeq: ${id}\r\n`; + let req = `${requestName} ${url || this.url} RTSP/1.0\r\nCSeq: ${id}\r\n`; const headers = Object.assign(Object.assign({}, this.headers), headersParam); // NOTE: // If we cache the Authenitcation Type (Direct or Basic) then we could @@ -379,7 +388,7 @@ class RTSPClient extends events_1.EventEmitter { .join(""); this.emit("log", req, "C->S"); // Make sure to add an empty line after the request. - this._client.write(`${req}\r\n`); + this.client.write(`${req}\r\n`); return new Promise((resolve, reject) => { const responseHandler = (responseName, resHeaders, mediaHeaders) => { const firstAnswer = String(resHeaders[""]) || ""; @@ -436,13 +445,13 @@ class RTSPClient extends events_1.EventEmitter { // Select Hash Function, default to MD5 const HashFunction = (algorithm == "SHA-256" ? util_1.getSHA256Hash : util_1.getMD5Hash); const ha1 = HashFunction(`${this.username}:${realm}:${this.password}`); - const ha2 = HashFunction(`${requestName}:${this._url}`); + const ha2 = HashFunction(`${requestName}:${this.url}`); const ha3 = HashFunction(`${ha1}:${nonce}:${ha2}`); // Some RTSP servers to not accept "algorithm=NNN" in the authString and reject the authentication. So only add algorithm=ZZZZ when not using MD5 if (algorithm == "MD5") - authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",uri="${this._url}",response="${ha3}"`; + authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",uri="${this.url}",response="${ha3}"`; else - authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",algorithm=${algorithm},uri="${this._url}",response="${ha3}"`; + authString = `Digest username="${this.username}",realm="${realm}",nonce="${nonce}",algorithm=${algorithm},uri="${this.url}",response="${ha3}"`; } else if (type === "Basic") { // Basic Authentication @@ -464,7 +473,7 @@ class RTSPClient extends events_1.EventEmitter { }); } respond(status, headersParam = {}) { - if (!this._client) { + if (!this.client) { return; } // mutable via string addition @@ -474,19 +483,19 @@ class RTSPClient extends events_1.EventEmitter { .map(([key, value]) => `${key}: ${value}\r\n`) .join(""); this.emit("log", res, "C->S"); - this._client.write(`${res}\r\n`); + this.client.write(`${res}\r\n`); } async play() { if (!this.isConnected) { throw new Error("Client is not connected."); } - await this.request("PLAY", { Session: this._session }); + await this.request("PLAY", { Session: this.session }); } async pause() { if (!this.isConnected) { throw new Error("Client is not connected."); } - await this.request("PAUSE", { Session: this._session }); + await this.request("PAUSE", { Session: this.session }); } async sendAudioBackChannel(audioChunk) { let rtp, buf; @@ -521,7 +530,7 @@ class RTSPClient extends events_1.EventEmitter { interleavedHeader = Buffer.concat([interleavedHeader, Buffer.from([channelInterleaved])]); interleavedHeader = Buffer.concat([interleavedHeader, bufferLength]); const dataToSend = Buffer.concat([interleavedHeader, rtp.packet]); - await this._socketWrite(this.tcpSocket, dataToSend); + await this.socketWrite(this.tcpSocket, dataToSend); } return; } @@ -529,24 +538,24 @@ class RTSPClient extends events_1.EventEmitter { if (this.closed) return; this.closed = true; - if (!this._client) { + if (!this.client) { return; } if (!isImmediate) { await this.request("TEARDOWN", { - Session: this._session, + Session: this.session, }); } - this._client.end(); + this.client.end(); this.removeAllListeners("response"); - if (this._keepAliveID != undefined) { - clearInterval(this._keepAliveID); - this._keepAliveID = undefined; + if (this.keepAliveID != undefined) { + clearInterval(this.keepAliveID); + this.keepAliveID = undefined; } this.isConnected = false; - this._cSeq = 0; + this.cSeq = 0; } - _onData(data) { + onData(data) { let index = 0; // $ const PACKET_START = 0x24; @@ -586,7 +595,7 @@ class RTSPClient extends events_1.EventEmitter { const packetChannel = this.messageBytes[1]; if ((packetChannel & 0x01) === 0) { // even number - let packet = (0, util_1.parseRTPPacket)(this.rtspPacket); + const packet = (0, util_1.parseRTPPacket)(this.rtspPacket); // Get the Session Detail const detail = this.setupResult.find(item => item.rtpChannel == packetChannel); if (detail != undefined) @@ -598,7 +607,7 @@ class RTSPClient extends events_1.EventEmitter { const packet = (0, util_1.parseRTCPPacket)(this.rtspPacket); // If this is a Sender Report, cache the NTP Wall Clock data if (packet.packetType == 200 && packet.senderReport != undefined) { - let detail = this.setupResult.find(item => item.rtcpChannel == packetChannel); + const detail = this.setupResult.find(item => item.rtcpChannel == packetChannel); if (detail != undefined) { detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW; detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW; @@ -606,8 +615,8 @@ class RTSPClient extends events_1.EventEmitter { } } this.emit("controlData", packetChannel, packet); - const receiver_report = this._emptyReceiverReport(); - this._sendInterleavedData(packetChannel, receiver_report); + const receiver_report = this.emptyReceiverReport(); + this.sendInterleavedData(packetChannel, receiver_report); } this.readState = ReadStates.SEARCHING; } @@ -687,8 +696,8 @@ class RTSPClient extends events_1.EventEmitter { } } // end while } - _sendInterleavedData(channel, buffer) { - if (!this._client) { + sendInterleavedData(channel, buffer) { + if (!this.client) { return; } const req = `${buffer.length} bytes of interleaved data on channel ${channel}`; @@ -699,16 +708,16 @@ class RTSPClient extends events_1.EventEmitter { header[2] = (buffer.length >> 8) & 0xff; header[3] = (buffer.length >> 0) & 0xff; const data = Buffer.concat([header, buffer]); - this._client.write(data); + this.client.write(data); } - _sendUDPData(host, port, buffer) { + sendUDPData(host, port, buffer) { const udp = dgram.createSocket("udp4"); - udp.send(buffer, 0, buffer.length, port, host, (err, bytes) => { + udp.send(buffer, 0, buffer.length, port, host, (_err, _bytes) => { // TODO: Don't ignore errors. udp.close(); }); } - _emptyReceiverReport() { + emptyReceiverReport() { const report = Buffer.alloc(8); const version = 2; const paddingBit = 0; @@ -725,7 +734,7 @@ class RTSPClient extends events_1.EventEmitter { report[7] = (this.clientSSRC >> 0) & 0xff; return report; } - async _socketWrite(socket, data) { + async socketWrite(socket, data) { return new Promise((resolve, reject) => { setTimeout(() => { socket.write(data, (error) => { @@ -743,11 +752,11 @@ class RTSPClient extends events_1.EventEmitter { GetWallClockTime(packet, detail) { // Add Wall Clock Time if (detail.sr_ntpMSW != undefined && detail.sr_ntpLSW != undefined && detail.sr_rtptimestamp != undefined && detail.mediaSource.rtp[0].rate != undefined) { - let refTimestampSecs = detail.sr_rtptimestamp / detail.mediaSource.rtp[0].rate; // H264 is 90 kHz clock rate - let packetTimestampSecs = packet.timestamp / detail.mediaSource.rtp[0].rate; // eg 90kHz - let packetTimestampDeltaSecs = packetTimestampSecs - refTimestampSecs; - let refTimestamp = new Date(this.ntpBaseDate_ms + (detail.sr_ntpMSW * 1000) + ((detail.sr_ntpLSW / Math.pow(2, 32)) * 1000)); - let wallclockTime = new Date(refTimestamp.getTime() + (packetTimestampDeltaSecs * 1000)); + const refTimestampSecs = detail.sr_rtptimestamp / detail.mediaSource.rtp[0].rate; // H264 is 90 kHz clock rate + const packetTimestampSecs = packet.timestamp / detail.mediaSource.rtp[0].rate; // eg 90kHz + const packetTimestampDeltaSecs = packetTimestampSecs - refTimestampSecs; + const refTimestamp = new Date(this.ntpBaseDate_ms + (detail.sr_ntpMSW * 1000) + ((detail.sr_ntpLSW / Math.pow(2, 32)) * 1000)); + const wallclockTime = new Date(refTimestamp.getTime() + (packetTimestampDeltaSecs * 1000)); return wallclockTime; } // Could not generate a Wall Clock Time diff --git a/dist/RTSPClient.js.map b/dist/RTSPClient.js.map index 7ef0601..2eea576 100644 --- a/dist/RTSPClient.js.map +++ b/dist/RTSPClient.js.map @@ -1 +1 @@ -{"version":3,"file":"RTSPClient.js","sourceRoot":"","sources":["../lib/RTSPClient.ts"],"names":[],"mappings":"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","sourcesContent":["import * as net from \"net\";\nimport * as dgram from \"dgram\";\nimport { parse as urlParse } from \"url\";\nimport { EventEmitter } from \"events\";\n\nimport {\n parseRTPPacket,\n parseRTCPPacket,\n getMD5Hash,\n Transport,\n parseTransport,\n generateSSRC,\n} from \"./util\";\n\nimport * as transform from \"sdp-transform\";\nimport RTPPacket from \"./transports/RTPPacket\";\nconst RTP_AVP = \"RTP/AVP\";\n\nconst STATUS_OK = 200;\nconst STATUS_UNAUTH = 401;\n\n// The WWW_AUTH is of the format\n// TOKEN key=value\n// TOKEN key1=value1,key2=value2\n// TOKEN key1=\"value1\",key2=value2\n\n// RegEx reminder ? = Zero or One item\n// * = Zero or More items\n// + = 1 or More items\n// \\s is whitespace. But we need to 'escape the slash', hence \\\\s (or put the regex in / / characters)\n// ?= is a lookahead\n\n// The RegEx has two 'Groups'\n// \n// Group 1 (finding the Key)\n// Look for one or more characters (a..z or A..Z)\n// then look for whitespace\n// then look for 'equals'\n// then look for whitespace\n// then look for an optional Quote character\n//\n// Group 2 (finding the Value) -\n// Look for EITHER 'look backwards for a Quote', some characters, 'lookahead for a Quote'\n// OR some characters until (by looking ahead) you can see that another key comes next. The lookahead is 'optinal whitespace' 'comma' 'optional whitespace' 'chars' 'optinal whitespace' 'equals'\n// OR some characters followed by 'optinal whitespace'\n\nconst WWW_AUTH = \"WWW-Authenticate\";\nconst WWW_AUTH_REGEX = new RegExp('([a-zA-Z]+)\\\\s*=\\\\s*\"?((?<=\").*?(?=\")|.*?(?=\\\\s*,?\\\\s*[a-zA-Z]+\\\\s*=)|.+[^\\\\s])', \"g\");\n\nenum ReadStates {\n SEARCHING,\n READING_RTSP_HEADER,\n READING_RTSP_PAYLOAD,\n READING_RAW_PACKET_SIZE,\n READING_RAW_PACKET,\n}\n\ntype Connection = \"udp\" | \"tcp\";\n\ntype Headers = {\n [key: string]: string | number | undefined;\n Session?: string;\n Location?: string;\n CSeq?: number;\n \"WWW-Authenticate\"?: string;\n Transport?: string;\n Unsupported?: string;\n};\n\ntype Detail = {\n codec: string;\n mediaSource: ({ // cannot work out how to pull this type in\n type: string;\n port: number;\n protocol: string;\n payloads?: string | undefined;\n } & transform.MediaDescription); // get Type from the interface\n transport: Transport['parameters']; // get Type from the interface\n isH264: boolean; // legacy API\n rtpChannel: number;\n rtcpChannel: number;\n};\n\nexport default class RTSPClient extends EventEmitter {\n username: string;\n password: string;\n headers: { [key: string]: string };\n\n isConnected = false;\n closed = false;\n\n // These are all set in #connect or #_netConnect.\n\n _url?: string;\n _client?: net.Socket;\n _cSeq = 0;\n _unsupportedExtensions?: string[];\n // Example: 'SessionId'[';timeout=seconds']\n _session?: string;\n _keepAliveID?: NodeJS.Timeout;\n _nextFreeInterleavedChannel = 0;\n _nextFreeUDPPort = 5000;\n\n readState: ReadStates = ReadStates.SEARCHING;\n\n // Used as a cache for the data stream.\n // What's in here is based on current #readState.\n messageBytes: number[] = [];\n\n // Used for parsing RTSP responses,\n\n // Content-Length header in the RTSP message.\n rtspContentLength = 0;\n rtspStatusLine = \"\";\n rtspHeaders: Headers = {};\n\n // Used for parsing RTP/RTCP responses.\n\n rtspPacketLength = 0;\n rtspPacket: Buffer = new Buffer(\"\");\n rtspPacketPointer = 0;\n\n // Used in #_emptyReceiverReport.\n clientSSRC = generateSSRC();\n\n tcpSocket: net.Socket = new net.Socket();\n setupResult: Array = [];\n constructor(\n username: string,\n password: string,\n headers?: { [key: string]: string }\n ) {\n super();\n\n this.username = username;\n this.password = password;\n this.headers = {\n ...(headers || {}),\n \"User-Agent\": \"yellowstone/3.x\",\n };\n }\n\n // This manages the lifecycle for the RTSP connection\n // over TCP.\n //\n // Sets #_client.\n //\n // Handles receiving data & closing port, called during\n // #connect.\n _netConnect(hostname: string, port: number): Promise {\n return new Promise((resolve, reject) => {\n // Set after listeners defined.\n\n const errorListener = (err: any) => {\n client.removeListener(\"error\", errorListener);\n reject(err);\n };\n\n const postConnectErrorListener = (err: any) => {\n client.removeListener(\"error\", postConnectErrorListener);\n this.emit(\"error\", err);\n reject(err);\n };\n\n const closeListener = () => {\n client.removeListener(\"close\", closeListener);\n this.emit(\"close\");\n this.close(true);\n };\n\n const responseListener = (responseName: string, headers: Headers) => {\n const name = responseName.split(\" \")[0];\n\n if (name.indexOf(\"RTSP/\") === 0) {\n return;\n }\n\n if (name === \"REDIRECT\" || name === \"ANNOUNCE\") {\n this.respond(\"200 OK\", { CSeq: headers.CSeq });\n }\n\n if (name === \"REDIRECT\" && headers.Location) {\n this.close();\n this.connect(headers.Location);\n }\n };\n\n const client = net.connect(port, hostname, () => {\n this.isConnected = true;\n this._client = client;\n\n client.removeListener(\"error\", errorListener);\n client.on(\"error\", postConnectErrorListener);\n\n this.on(\"response\", responseListener);\n resolve(this);\n });\n\n client.on(\"data\", this._onData.bind(this));\n client.on(\"error\", errorListener);\n client.on(\"close\", closeListener);\n this.tcpSocket = client;\n });\n }\n\n async connect(\n url: string,\n {\n keepAlive = true,\n connection = \"udp\",\n }: { keepAlive: boolean; connection?: Connection } = {\n keepAlive: true,\n connection: \"udp\",\n }\n ): Promise {\n const { hostname, port } = urlParse((this._url = url));\n if (!hostname) {\n throw new Error(\"URL parsing error in connect method.\");\n }\n\n const details: Detail[] = [];\n\n await this._netConnect(hostname, parseInt(port || \"554\"));\n await this.request(\"OPTIONS\");\n\n const describeRes = await this.request(\"DESCRIBE\", {\n Accept: \"application/sdp\",\n });\n if (!describeRes || !describeRes.mediaHeaders) {\n throw new Error(\n \"No media headers on DESCRIBE; RTSP server is broken (sanity check)\"\n );\n }\n\n // For now, only RTP/AVP is supported.\n const { media } = transform.parse(describeRes.mediaHeaders.join(\"\\r\\n\"));\n\n // Loop over the Media Streams in the SDP looking for Video or Audio\n // In theory the SDP can contain multiple Video and Audio Streams. We only want one of each type\n let hasVideo = false;\n let hasAudio = false;\n let hasMetaData = false;\n let hasBackchannel = false;\n\n for (let x = 0; x < media.length; x++) {\n let needSetup = false;\n let codec = \"\";\n const mediaSource = media[x];\n\n\n // RFC says \"If none of the direction attributes (\"sendonly\", \"recvonly\", \"inactive\", and \"sendrecv\") are present,\n // the \"sendrecv\" SHOULD be assumed\n if (mediaSource.direction == undefined) mediaSource.direction = \"sendrecv\"; // Wowza does not send 'direction'\n\n if (\n mediaSource.type === \"video\" &&\n mediaSource.protocol === RTP_AVP &&\n mediaSource.rtp[0].codec === \"H264\"\n ) {\n this.emit(\"log\", \"H264 Video Stream Found in SDP\", \"\");\n if (hasVideo == false) {\n needSetup = true;\n hasVideo = true;\n codec = \"H264\";\n }\n }\n\n if (\n mediaSource.type === \"video\" &&\n mediaSource.protocol === RTP_AVP &&\n mediaSource.rtp[0].codec === \"H265\"\n ) {\n this.emit(\"log\", \"H265 Video Stream Found in SDP\", \"\");\n if (hasVideo == false) {\n needSetup = true;\n hasVideo = true;\n codec = \"H265\";\n }\n }\n\n\n if (\n mediaSource.type === \"audio\" &&\n (mediaSource.direction === \"recvonly\" || mediaSource.direction === \"sendrecv\") &&\n mediaSource.protocol === RTP_AVP &&\n mediaSource.rtp[0].codec.toLowerCase() === \"mpeg4-generic\" && // (RFC examples are lower case. Axis cameras use upper case)\n mediaSource.fmtp[0].config.includes(\"AAC\")\n ) {\n this.emit(\"log\", \"AAC Audio Stream Found in SDP\", \"\");\n if (hasAudio == false) {\n needSetup = true;\n hasAudio = true;\n codec = \"AAC\";\n }\n }\n\n if (mediaSource.type === \"audio\" &&\n mediaSource.direction === \"sendonly\" &&\n mediaSource.protocol === RTP_AVP) {\n this.emit(\"log\", \"Audio backchannel Found in SDP\", \"\");\n if (hasBackchannel == false) {\n needSetup = true;\n hasBackchannel = true;\n codec = mediaSource.rtp[0].codec;\n }\n }\n\n if (\n mediaSource.type === \"application\" &&\n mediaSource.protocol === RTP_AVP &&\n mediaSource.rtp[0].codec.toLowerCase() === \"vnd.onvif.metadata\"\n ) {\n this.emit(\"log\", \"ONVIF Meta Data Found in SDP\", \"\");\n if (hasMetaData == false) {\n needSetup = true;\n hasMetaData = true;\n codec = \"vnd.onvif.metadata\";\n }\n }\n\n if (needSetup) {\n let streamurl = \"\";\n // The 'control' in the SDP can be a relative or absolute uri\n if (mediaSource.control) {\n if (mediaSource.control.toLowerCase().startsWith(\"rtsp://\")) {\n // absolute path\n streamurl = mediaSource.control;\n } else {\n // relative path\n streamurl = this._url + \"/\" + mediaSource.control;\n }\n }\n\n // Perform a SETUP on the streamurl\n // either 'udp' RTP/RTCP packets\n // or with 'tcp' RTP/TCP packets which are interleaved into the TCP based RTSP socket\n let setupRes;\n let rtpChannel;\n let rtcpChannel;\n let rtpReceiver: dgram.Socket|null = null; // UDP mode init value\n let rtcpReceiver: dgram.Socket|null = null; // UDP mode init value\n\n if (connection === \"udp\") {\n // Create a pair of UDP listeners, even numbered port for RTP\n // and odd numbered port for RTCP\n\n rtpChannel = this._nextFreeUDPPort;\n rtcpChannel = this._nextFreeUDPPort + 1;\n this._nextFreeUDPPort += 2;\n\n const rtpPort = rtpChannel;\n rtpReceiver = dgram.createSocket(\"udp4\");\n\n rtpReceiver.on(\"message\", (buf, remote) => {\n const packet = parseRTPPacket(buf);\n this.emit(\"data\", rtpPort, packet.payload, packet);\n });\n\n const rtcpPort = rtcpChannel;\n rtcpReceiver = dgram.createSocket(\"udp4\");\n\n rtcpReceiver.on(\"message\", (buf, remote) => {\n const packet = parseRTCPPacket(buf);\n this.emit(\"controlData\", rtcpPort, packet);\n\n const receiver_report = this._emptyReceiverReport();\n this._sendUDPData(remote.address, remote.port, receiver_report);\n });\n\n // Block until both UDP sockets are open.\n\n await new Promise((resolve) => {\n rtpReceiver?.bind(rtpPort, () => resolve({}));\n });\n\n await new Promise((resolve) => {\n rtcpReceiver?.bind(rtcpPort, () => resolve({}));\n });\n\n const setupHeader = {\n Transport: `RTP/AVP;unicast;client_port=${rtpPort}-${rtcpPort}`,\n };\n if (this._session)\n Object.assign(setupHeader, { Session: this._session });\n setupRes = await this.request(\"SETUP\", setupHeader, streamurl);\n } else if (connection === \"tcp\") {\n // channel 0, RTP\n // channel 1, RTCP\n\n rtpChannel = this._nextFreeInterleavedChannel;\n rtcpChannel = this._nextFreeInterleavedChannel + 1;\n this._nextFreeInterleavedChannel += 2;\n\n const setupHeader = {\n Transport: `RTP/AVP/TCP;interleaved=${rtpChannel}-${rtcpChannel}`,\n };\n if (this._session)\n Object.assign(setupHeader, { Session: this._session }); // not used on first SETUP\n setupRes = await this.request(\"SETUP\", setupHeader, streamurl);\n } else {\n throw new Error(\n `Connection parameter to RTSPClient#connect is ${connection}, not udp or tcp!`\n );\n }\n\n if (!setupRes) {\n throw new Error(\n \"No SETUP response; RTSP server is broken (sanity check)\"\n );\n }\n\n const { headers } = setupRes;\n\n if (!headers.Transport) {\n throw new Error(\n \"No Transport header on SETUP; RTSP server is broken (sanity check)\"\n );\n }\n\n const transport = parseTransport(headers.Transport);\n if (\n transport.protocol !== \"RTP/AVP/TCP\" &&\n transport.protocol !== \"RTP/AVP\"\n ) {\n throw new Error(\n \"Only RTSP servers supporting RTP/AVP(unicast) or RTP/ACP/TCP are supported at this time.\"\n );\n }\n\n // Patch from zoolyka (Zoltan Hajdu).\n // Try to open a hole in the NAT router (to allow incoming UDP packets)\n // by send a UDP packet for RTP and RTCP to the remote RTSP server.\n // Note, Roger did not have a router that needed this so the feature is untested.\n // May be better to change the RTCP message to a Receiver Report, leaving the RTP message as zero bytes\n if (connection === \"udp\" && transport && rtpReceiver && rtcpReceiver) {\n rtpReceiver.send(Buffer.from(''), Number(transport.parameters[\"server_port\"].split(\"-\")[0]), hostname);\n rtcpReceiver.send(Buffer.from(''), Number(transport.parameters[\"server_port\"].split(\"-\")[1]), hostname);\n }\n\n if (headers.Unsupported) {\n this._unsupportedExtensions = headers.Unsupported.split(\",\");\n }\n\n if (headers.Session) {\n this._session = headers.Session.split(\";\")[0];\n }\n\n const detail: Detail = {\n codec,\n mediaSource,\n transport: transport.parameters,\n isH264: codec === \"H264\",\n rtpChannel,\n rtcpChannel,\n };\n\n details.push(detail);\n } // end if (needSetup)\n } // end for loop, looping over each media stream\n\n if (keepAlive) {\n // Start a Timer to send OPTIONS every 20 seconds to keep stream alive\n // using the Session ID\n this._keepAliveID = setInterval(() => {\n this.request(\"OPTIONS\", { Session: this._session });\n // this.request(\"OPTIONS\");\n }, 20 * 1000);\n }\n\n this.setupResult = details;\n return details;\n }\n\n request(\n requestName: string,\n headersParam: Headers = {},\n url?: string\n ): Promise<{ headers: Headers; mediaHeaders?: string[] } | void> {\n if (!this._client) {\n return Promise.resolve();\n }\n\n const id = ++this._cSeq;\n // mutable via string addition\n let req = `${requestName} ${url || this._url} RTSP/1.0\\r\\nCSeq: ${id}\\r\\n`;\n\n const headers = {\n ...this.headers,\n ...headersParam,\n };\n\n // NOTE:\n // If we cache the Authenitcation Type (Direct or Basic) then we could\n // re-compute an Authorization Header here and include in the RTSP Command\n // This would make connections a faster with fewer round-trips to the RTSP Server\n\n req += Object.entries(headers)\n .map(([key, value]) => `${key}: ${value}\\r\\n`)\n .join(\"\");\n\n this.emit(\"log\", req, \"C->S\");\n // Make sure to add an empty line after the request.\n this._client.write(`${req}\\r\\n`);\n\n return new Promise((resolve, reject) => {\n const responseHandler = (\n responseName: string,\n resHeaders: Headers,\n mediaHeaders: string[]\n ) => {\n const firstAnswer: string = String(resHeaders[\"\"]) || \"\";\n if (firstAnswer.indexOf(\"401\") >= 0 && 'Authorization' in headers) {\n // If the RTSP Command we sent included an Authorization and we have 401 error, then reject()\n reject(new Error(`Bad RTSP credentials!`));\n return;\n }\n if (resHeaders.CSeq !== id) {\n return;\n }\n\n this.removeListener(\"response\", responseHandler);\n\n const statusCode = parseInt(responseName.split(\" \")[1]);\n\n if (statusCode === STATUS_OK) {\n if (mediaHeaders.length > 0) {\n resolve({\n headers: resHeaders,\n mediaHeaders,\n });\n } else {\n resolve({\n headers: resHeaders,\n });\n }\n } else {\n const authHeader = resHeaders[WWW_AUTH];\n\n // We have status code unauthenticated.\n if (statusCode === STATUS_UNAUTH && authHeader) {\n const type = authHeader.split(\" \")[0];\n\n // Get auth properties from WWW_AUTH header.\n let realm = \"\";\n let nonce = \"\";\n\n let match = WWW_AUTH_REGEX.exec(authHeader);\n while (match != null) {\n const prop = match[1];\n\n if (prop == \"realm\" && match[2]) {\n realm = match[2];\n }\n\n if (prop == \"nonce\" && match[2]) {\n nonce = match[2];\n }\n\n match = WWW_AUTH_REGEX.exec(authHeader);\n }\n\n // mutable, corresponds to Authorization header\n let authString = \"\";\n\n if (type === \"Digest\") {\n // Digest Authentication\n\n const ha1 = getMD5Hash(\n `${this.username}:${realm}:${this.password}`\n );\n const ha2 = getMD5Hash(`${requestName}:${this._url}`);\n const ha3 = getMD5Hash(`${ha1}:${nonce}:${ha2}`);\n\n authString = `Digest username=\"${this.username}\",realm=\"${realm}\",nonce=\"${nonce}\",uri=\"${this._url}\",response=\"${ha3}\"`;\n } else if (type === \"Basic\") {\n // Basic Authentication\n // https://xkcd.com/538/\n const b64 = new Buffer(\n `${this.username}:${this.password}`\n ).toString(\"base64\");\n authString = `Basic ${b64}`;\n }\n\n Object.assign(headers, {\n Authorization: authString,\n });\n\n resolve(this.request(requestName, headers, url)); // Call this.request with Authorized request\n return;\n }\n\n reject(new Error(`Bad RTSP status code ${statusCode}!`));\n return;\n }\n };\n\n this.on(\"response\", responseHandler);\n });\n }\n\n respond(status: string, headersParam: Headers = {}): void {\n if (!this._client) {\n return;\n }\n\n // mutable via string addition\n let res = `RTSP/1.0 ${status}\\r\\n`;\n\n const headers = {\n ...this.headers,\n ...headersParam,\n };\n\n res += Object.entries(headers)\n .map(([key, value]) => `${key}: ${value}\\r\\n`)\n .join(\"\");\n\n this.emit(\"log\", res, \"C->S\");\n this._client.write(`${res}\\r\\n`);\n }\n\n async play(): Promise {\n if (!this.isConnected) {\n throw new Error(\"Client is not connected.\");\n }\n\n await this.request(\"PLAY\", { Session: this._session });\n }\n\n async pause(): Promise {\n if (!this.isConnected) {\n throw new Error(\"Client is not connected.\");\n }\n\n await this.request(\"PAUSE\", { Session: this._session });\n }\n\n async sendAudioBackChannel(audioChunk: Buffer): Promise {\n let rtp, buf;\n const bufSize = 160;\n while (audioChunk.length > 0) {\n if (audioChunk.length > bufSize) {\n buf = audioChunk.slice(0, bufSize);\n audioChunk = audioChunk.slice(bufSize, audioChunk.length);\n } else {\n buf = audioChunk.slice(0, audioChunk.length);\n audioChunk = Buffer.from([]);\n }\n if (!rtp)\n rtp = new RTPPacket(buf);\n else\n rtp.payload = buf;\n // rtp.type = 8;// set động\n rtp.time += buf.length;\n rtp.seq++;\n const bufferLength = Buffer.alloc(2);\n bufferLength.writeUInt16BE(rtp.packet.length, 0);\n let channelInterleaved = this.setupResult.filter((value) => {\n return value.mediaSource.type === 'audio' && value.mediaSource.direction === 'sendonly';\n })[0].transport.interleaved;\n /* RTSP Interleaved Frame structure\n |dollar sign|channel identifier|data length|\n |1 Byte |1 Byte |2 Bytes |\n */\n channelInterleaved = channelInterleaved.split('-')[0];\n let interleavedHeader = Buffer.from([0x24]);// set '$'\n interleavedHeader = Buffer.concat([interleavedHeader, Buffer.from([channelInterleaved])]);\n interleavedHeader = Buffer.concat([interleavedHeader, bufferLength]);\n const dataToSend = Buffer.concat([interleavedHeader, rtp.packet]);\n await this._socketWrite(this.tcpSocket, dataToSend);\n }\n return;\n }\n\n async close(isImmediate = false): Promise {\n if (this.closed) return;\n this.closed = true;\n\n if (!this._client) {\n return;\n }\n\n if (!isImmediate) {\n await this.request(\"TEARDOWN\", {\n Session: this._session,\n });\n }\n\n this._client.end();\n this.removeAllListeners(\"response\");\n\n if (this._keepAliveID != undefined) {\n clearInterval(this._keepAliveID);\n this._keepAliveID = undefined;\n }\n\n this.isConnected = false;\n this._cSeq = 0;\n }\n\n _onData(data: Buffer): void {\n let index = 0;\n\n // $\n const PACKET_START = 0x24;\n // R\n const RTSP_HEADER_START = 0x52;\n // /n\n const ENDL = 10;\n\n while (index < data.length) {\n // read RTP or RTCP packet\n if (\n this.readState == ReadStates.SEARCHING &&\n data[index] == PACKET_START\n ) {\n this.messageBytes = [data[index]];\n index++;\n\n this.readState = ReadStates.READING_RAW_PACKET_SIZE;\n } else if (this.readState == ReadStates.READING_RAW_PACKET_SIZE) {\n // accumulate bytes for $, channel and length\n this.messageBytes.push(data[index]);\n index++;\n\n if (this.messageBytes.length == 4) {\n this.rtspPacketLength =\n (this.messageBytes[2] << 8) + this.messageBytes[3];\n\n if (this.rtspPacketLength > 0) {\n this.rtspPacket = new Buffer(this.rtspPacketLength);\n this.rtspPacketPointer = 0;\n this.readState = ReadStates.READING_RAW_PACKET;\n } else {\n this.readState = ReadStates.SEARCHING;\n }\n }\n } else if (this.readState == ReadStates.READING_RAW_PACKET) {\n this.rtspPacket[this.rtspPacketPointer++] = data[index];\n index++;\n\n if (this.rtspPacketPointer == this.rtspPacketLength) {\n const packetChannel = this.messageBytes[1];\n if ((packetChannel & 0x01) === 0) {\n // even number\n const packet = parseRTPPacket(this.rtspPacket);\n this.emit(\"data\", packetChannel, packet.payload, packet);\n }\n if ((packetChannel & 0x01) === 1) {\n // odd number\n const packet = parseRTCPPacket(this.rtspPacket);\n this.emit(\"controlData\", packetChannel, packet);\n const receiver_report = this._emptyReceiverReport();\n this._sendInterleavedData(packetChannel, receiver_report);\n }\n this.readState = ReadStates.SEARCHING;\n }\n // read response data\n } else if (\n this.readState == ReadStates.SEARCHING &&\n data[index] == RTSP_HEADER_START\n ) {\n // found the start of a RTSP rtsp_message\n this.messageBytes = [data[index]];\n index++;\n\n this.readState = ReadStates.READING_RTSP_HEADER;\n } else if (this.readState == ReadStates.READING_RTSP_HEADER) {\n // Reading a RTSP message.\n\n // Add character to the messageBytes\n // Ignore /r (13) but keep /n (10)\n if (data[index] != 13) {\n this.messageBytes.push(data[index]);\n }\n index++;\n\n // if we have two new lines back to back then we have a complete RTSP command,\n // note we may still need to read the Content Payload (the body) e.g. the SDP\n if (\n this.messageBytes.length >= 2 &&\n this.messageBytes[this.messageBytes.length - 2] == ENDL &&\n this.messageBytes[this.messageBytes.length - 1] == ENDL\n ) {\n // Parse the Header\n\n const text = String.fromCharCode.apply(null, this.messageBytes);\n const lines = text.split(\"\\n\");\n\n this.rtspContentLength = 0;\n this.rtspStatusLine = lines[0];\n this.rtspHeaders = {};\n\n lines.forEach((line) => {\n const indexOf = line.indexOf(\":\");\n\n if (indexOf !== line.length - 1) {\n const key = line.substring(0, indexOf).trim();\n const data = line.substring(indexOf + 1).trim();\n\n this.rtspHeaders[key] =\n key != \"Session\" && data.match(/^[0-9]+$/)\n ? parseInt(data, 10)\n : data;\n\n // workaround for buggy Hipcam RealServer/V1.0 camera which returns Content-length and not Content-Length\n if (key.toLowerCase() == \"content-length\") {\n this.rtspContentLength = parseInt(data, 10);\n }\n }\n });\n\n // if no content length, there there's no media headers\n // emit the message\n if (!this.rtspContentLength) {\n this.emit(\"log\", text, \"S->C\");\n\n this.emit(\"response\", this.rtspStatusLine, this.rtspHeaders, []);\n this.readState = ReadStates.SEARCHING;\n } else {\n this.messageBytes = [];\n this.readState = ReadStates.READING_RTSP_PAYLOAD;\n }\n }\n } else if (\n this.readState == ReadStates.READING_RTSP_PAYLOAD &&\n this.messageBytes.length < this.rtspContentLength\n ) {\n // Copy data into the RTSP payload\n this.messageBytes.push(data[index]);\n index++;\n\n if (this.messageBytes.length == this.rtspContentLength) {\n const text = String.fromCharCode.apply(null, this.messageBytes);\n const mediaHeaders = text.split(\"\\n\");\n\n // Emit the RTSP message\n this.emit(\n \"log\",\n String.fromCharCode.apply(null, this.messageBytes) + text,\n \"S->C\"\n );\n\n this.emit(\n \"response\",\n this.rtspStatusLine,\n this.rtspHeaders,\n mediaHeaders\n );\n this.readState = ReadStates.SEARCHING;\n }\n } else {\n // unexpected data\n throw new Error(\n \"Bug in RTSP data framing, please file an issue with the author with stacktrace.\"\n );\n }\n } // end while\n }\n\n _sendInterleavedData(channel: number, buffer: Buffer): void {\n if (!this._client) {\n return;\n }\n\n const req = `${buffer.length} bytes of interleaved data on channel ${channel}`;\n this.emit(\"log\", req, \"C->S\");\n\n const header = new Buffer(4);\n header[0] = 0x24; // ascii $\n header[1] = channel;\n header[2] = (buffer.length >> 8) & 0xff;\n header[3] = (buffer.length >> 0) & 0xff;\n\n const data = Buffer.concat([header, buffer]);\n this._client.write(data);\n }\n\n _sendUDPData(host: string, port: number, buffer: Buffer): void {\n const udp = dgram.createSocket(\"udp4\");\n udp.send(buffer, 0, buffer.length, port, host, (err, bytes) => {\n // TODO: Don't ignore errors.\n udp.close();\n });\n }\n\n _emptyReceiverReport(): Buffer {\n const report = new Buffer(8);\n const version = 2;\n const paddingBit = 0;\n const reportCount = 0; // an empty report\n const packetType = 201; // Receiver Report\n const length = report.length / 4 - 1; // num 32 bit words minus 1\n report[0] = (version << 6) + (paddingBit << 5) + reportCount;\n report[1] = packetType;\n report[2] = (length >> 8) & 0xff;\n report[3] = (length >> 0) & 0xff;\n report[4] = (this.clientSSRC >> 24) & 0xff;\n report[5] = (this.clientSSRC >> 16) & 0xff;\n report[6] = (this.clientSSRC >> 8) & 0xff;\n report[7] = (this.clientSSRC >> 0) & 0xff;\n\n return report;\n }\n\n async _socketWrite(socket: net.Socket, data: Buffer): Promise {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n socket.write(data, (error: any) => {\n if (error) {\n reject(error);\n } else {\n resolve(undefined);\n }\n })\n }, 20);\n })\n }\n}\n\nexport { RTPPacket, RTCPPacket } from \"./util\";\n"]} +{"version":3,"file":"RTSPClient.js","sourceRoot":"","sources":["../lib/RTSPClient.ts"],"names":[],"mappings":"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","sourcesContent":["import * as net from \"net\";\r\nimport * as tls from \"tls\";\r\n\r\n// Union of net.Socket and tls.TLSSocket\r\ntype SocketUnion = net.Socket | tls.TLSSocket;\r\n\r\nimport * as dgram from \"dgram\";\r\nimport { parse as urlParse } from \"url\";\r\nimport { EventEmitter } from \"events\";\r\n\r\nimport * as util from \"./util\";\r\n\r\nimport {\r\n parseRTPPacket,\r\n parseRTCPPacket,\r\n getMD5Hash,\r\n getSHA256Hash,\r\n Transport,\r\n parseTransport,\r\n generateSSRC,\r\n} from \"./util\";\r\n\r\nimport * as transform from \"sdp-transform\";\r\nimport RTPPacket from \"./transports/RTPPacket\";\r\nconst RTP_AVP = \"RTP/AVP\";\r\nconst RTP_AVPF = \"RTP/AVPF\"; // Used by AV1. This is RTP with Feedback (via RTCP) to request Keyframes via RTCP\r\n\r\nconst STATUS_OK = 200;\r\nconst STATUS_UNAUTH = 401;\r\n\r\n// The WWW_AUTH is of the format\r\n// TOKEN key=value\r\n// TOKEN key1=value1,key2=value2\r\n// TOKEN key1=\"value1\",key2=value2\r\n\r\n// RegEx reminder ? = Zero or One item\r\n// * = Zero or More items\r\n// + = 1 or More items\r\n// \\s is whitespace. But we need to 'escape the slash', hence \\\\s (or put the regex in / / characters)\r\n// ?= is a lookahead\r\n\r\n// The RegEx has two 'Groups'\r\n// \r\n// Group 1 (finding the Key)\r\n// Look for one or more characters (a..z or A..Z)\r\n// then look for whitespace\r\n// then look for 'equals'\r\n// then look for whitespace\r\n// then look for an optional Quote character\r\n//\r\n// Group 2 (finding the Value) -\r\n// Look for EITHER 'look backwards for a Quote', some characters, 'lookahead for a Quote'\r\n// OR some characters until (by looking ahead) you can see that another key comes next. The lookahead is 'optinal whitespace' 'comma' 'optional whitespace' 'chars' 'optinal whitespace' 'equals'\r\n// OR some characters followed by 'optinal whitespace'\r\n\r\nconst WWW_AUTH = \"WWW-Authenticate\";\r\nconst WWW_AUTH_REGEX = new RegExp('([a-zA-Z]+)\\\\s*=\\\\s*\"?((?<=\").*?(?=\")|.*?(?=\\\\s*,?\\\\s*[a-zA-Z]+\\\\s*=)|.+[^\\\\s])', \"g\");\r\n\r\nenum ReadStates {\r\n SEARCHING,\r\n READING_RTSP_HEADER,\r\n READING_RTSP_PAYLOAD,\r\n READING_RAW_PACKET_SIZE,\r\n READING_RAW_PACKET,\r\n}\r\n\r\ntype Connection = \"udp\" | \"tcp\";\r\n\r\ntype Headers = {\r\n [key: string]: string | number | undefined;\r\n Session?: string;\r\n Location?: string;\r\n CSeq?: number;\r\n \"WWW-Authenticate\"?: string;\r\n Transport?: string;\r\n Unsupported?: string;\r\n};\r\n\r\n// Details for each Session within the RTSP Stream (eg video session, audio session, metadata session)\r\ntype Detail = {\r\n codec: string;\r\n mediaSource: ({ // cannot work out how to pull this type in\r\n type: string;\r\n port: number;\r\n protocol: string;\r\n payloads?: string | undefined;\r\n } & transform.MediaDescription); // get Type from the interface\r\n transport: Transport['parameters']; // get Type from the interface\r\n isH264: boolean; // legacy API\r\n rtpChannel: number;\r\n rtcpChannel: number;\r\n\r\n // Cache any optional RTCP Sender Report values (used to calculate Wall Clock Time)\r\n sr_ntpMSW?: number;\r\n sr_ntpLSW?: number;\r\n sr_rtptimestamp?: number;\r\n};\r\n\r\nexport default class RTSPClient extends EventEmitter {\r\n username: string;\r\n password: string;\r\n headers: { [key: string]: string };\r\n\r\n isConnected = false;\r\n closed = false;\r\n\r\n // These are all set in #connect or #netConnect.\r\n\r\n private url?: string;\r\n private client?: SocketUnion;\r\n private cSeq = 0;\r\n private unsupportedExtensions?: string[];\r\n // Example: 'SessionId'[';timeout=seconds']\r\n protected session?: string; // protected for ONVIFClient access\r\n private keepAliveID?: NodeJS.Timeout;\r\n private nextFreeInterleavedChannel = 0;\r\n private nextFreeUDPPort = 5000;\r\n\r\n readState: ReadStates = ReadStates.SEARCHING;\r\n\r\n // Used as a cache for the data stream.\r\n // What's in here is based on current #readState.\r\n messageBytes: number[] = [];\r\n\r\n // Used for parsing RTSP responses,\r\n\r\n // Content-Length header in the RTSP message.\r\n rtspContentLength = 0;\r\n rtspStatusLine = \"\";\r\n rtspHeaders: Headers = {};\r\n\r\n // Used for parsing RTP/RTCP responses.\r\n\r\n rtspPacketLength = 0;\r\n rtspPacket = Buffer.from(\"\");\r\n rtspPacketPointer = 0;\r\n\r\n // Used in emptyReceiverReport.\r\n clientSSRC = generateSSRC();\r\n\r\n tcpSocket: SocketUnion = new net.Socket();\r\n setupResult: Array = [];\r\n constructor(\r\n username: string,\r\n password: string,\r\n headers?: { [key: string]: string }\r\n ) {\r\n super();\r\n\r\n this.username = username;\r\n this.password = password;\r\n this.headers = {\r\n ...(headers || {}),\r\n \"User-Agent\": \"yellowstone/3.x\",\r\n };\r\n }\r\n\r\n // This manages the lifecycle for the RTSP connection\r\n // over TCP.\r\n //\r\n // Sets #_client.\r\n //\r\n // Handles receiving data & closing port, called during\r\n // #connect.\r\n private netConnect(hostname: string, port: number, secure = false): Promise {\r\n return new Promise((resolve, reject) => {\r\n // Set after listeners defined.\r\n\r\n const errorListener = (err: Error) => {\r\n client.removeListener(\"error\", errorListener);\r\n reject(err);\r\n };\r\n\r\n const postConnectErrorListener = (err: Error) => {\r\n client.removeListener(\"error\", postConnectErrorListener);\r\n this.emit(\"error\", err);\r\n reject(err);\r\n };\r\n\r\n const closeListener = () => {\r\n client.removeListener(\"close\", closeListener);\r\n this.emit(\"close\");\r\n this.close(true);\r\n };\r\n\r\n const responseListener = (responseName: string, headers: Headers) => {\r\n const name = responseName.split(\" \")[0];\r\n\r\n if (name.indexOf(\"RTSP/\") === 0) {\r\n return;\r\n }\r\n\r\n if (name === \"REDIRECT\" || name === \"ANNOUNCE\") {\r\n this.respond(\"200 OK\", { CSeq: headers.CSeq });\r\n }\r\n\r\n if (name === \"REDIRECT\" && headers.Location) {\r\n this.close();\r\n this.connect(headers.Location);\r\n }\r\n };\r\n\r\n // rtsp or rtsps(with tls)\r\n let client: SocketUnion;\r\n if (secure == false) {\r\n client = net.connect(port, hostname, () => {\r\n this.isConnected = true;\r\n this.client = client;\r\n\r\n client.removeListener(\"error\", errorListener);\r\n client.on(\"error\", postConnectErrorListener);\r\n\r\n this.on(\"response\", responseListener);\r\n resolve(this);\r\n });\r\n }\r\n else {\r\n const options: tls.ConnectionOptions = {\r\n rejectUnauthorized: false\r\n };\r\n client = tls.connect(port, hostname, options, () => {\r\n console.log(\"TLS Connection\");\r\n this.isConnected = true;\r\n this.client = client;\r\n\r\n client.removeListener(\"error\", errorListener);\r\n\r\n this.on(\"response\", responseListener);\r\n resolve(this);\r\n });\r\n }\r\n\r\n client.on(\"data\", this.onData.bind(this));\r\n client.on(\"error\", errorListener);\r\n client.on(\"close\", closeListener);\r\n this.tcpSocket = client;\r\n });\r\n }\r\n\r\n async connect(\r\n url: string,\r\n {\r\n keepAlive = true,\r\n connection = \"udp\",\r\n secure = false,\r\n }: { keepAlive: boolean; connection?: Connection, secure: boolean } = {\r\n keepAlive: true,\r\n connection: \"udp\",\r\n secure: false\r\n }\r\n ): Promise {\r\n const { hostname, port } = urlParse((this.url = url));\r\n if (!hostname) {\r\n throw new Error(\"URL parsing error in connect method.\");\r\n }\r\n\r\n const details: Detail[] = [];\r\n\r\n await this.netConnect(hostname, parseInt(port || \"554\"), secure);\r\n await this.request(\"OPTIONS\");\r\n\r\n const describeRes = await this.request(\"DESCRIBE\", {\r\n Accept: \"application/sdp\",\r\n });\r\n if (!describeRes || !describeRes.mediaHeaders) {\r\n throw new Error(\r\n \"No media headers on DESCRIBE; RTSP server is broken (sanity check)\"\r\n );\r\n }\r\n\r\n // For now, only RTP/AVP and RTP/AVPF are supported. (Some RTSPS servers use RTP/SAVP)\r\n const { media } = transform.parse(describeRes.mediaHeaders.join(\"\\r\\n\"));\r\n\r\n // Loop over the Media Streams in the SDP looking for Video or Audio\r\n // In theory the SDP can contain multiple Video and Audio Streams. We only want one of each type\r\n let hasVideo = false;\r\n let hasAudio = false;\r\n let hasMetaData = false;\r\n let hasBackchannel = false;\r\n\r\n for (let x = 0; x < media.length; x++) {\r\n let needSetup = false;\r\n let codec = \"\";\r\n const mediaSource = media[x];\r\n\r\n\r\n // RFC says \"If none of the direction attributes (\"sendonly\", \"recvonly\", \"inactive\", and \"sendrecv\") are present,\r\n // the \"sendrecv\" SHOULD be assumed\r\n if (mediaSource.direction == undefined) mediaSource.direction = \"sendrecv\"; // Wowza does not send 'direction'\r\n\r\n if (\r\n mediaSource.type === \"video\" &&\r\n mediaSource.protocol === RTP_AVP &&\r\n mediaSource.rtp[0].codec === \"H264\"\r\n ) {\r\n this.emit(\"log\", \"H264 Video Stream Found in SDP\", \"\");\r\n if (hasVideo == false) {\r\n needSetup = true;\r\n hasVideo = true;\r\n codec = \"H264\";\r\n }\r\n }\r\n\r\n if (\r\n mediaSource.type === \"video\" &&\r\n mediaSource.protocol === RTP_AVP &&\r\n mediaSource.rtp[0].codec === \"H265\"\r\n ) {\r\n this.emit(\"log\", \"H265 Video Stream Found in SDP\", \"\");\r\n if (hasVideo == false) {\r\n needSetup = true;\r\n hasVideo = true;\r\n codec = \"H265\";\r\n }\r\n }\r\n\r\n if (\r\n mediaSource.type === \"video\" &&\r\n (mediaSource.protocol === RTP_AVP || mediaSource.protocol === RTP_AVPF) &&\r\n mediaSource.rtp[0].codec === \"AV1\"\r\n ) {\r\n this.emit(\"log\", \"AV1 Video Stream Found in SDP\", \"\");\r\n if (hasVideo == false) {\r\n needSetup = true;\r\n hasVideo = true;\r\n codec = \"AV1\";\r\n }\r\n }\r\n\r\n\r\n if (\r\n mediaSource.type === \"audio\" &&\r\n (mediaSource.direction === \"recvonly\" || mediaSource.direction === \"sendrecv\") &&\r\n mediaSource.protocol === RTP_AVP &&\r\n mediaSource.rtp[0].codec.toLowerCase() === \"mpeg4-generic\" && // (RFC examples are lower case. Axis cameras use upper case)\r\n mediaSource.fmtp[0].config.includes(\"AAC\")\r\n ) {\r\n this.emit(\"log\", \"AAC Audio Stream Found in SDP\", \"\");\r\n if (hasAudio == false) {\r\n needSetup = true;\r\n hasAudio = true;\r\n codec = \"AAC\";\r\n }\r\n }\r\n\r\n if (mediaSource.type === \"audio\" &&\r\n mediaSource.direction === \"sendonly\" &&\r\n mediaSource.protocol === RTP_AVP) {\r\n this.emit(\"log\", \"Audio backchannel Found in SDP\", \"\");\r\n if (hasBackchannel == false) {\r\n needSetup = true;\r\n hasBackchannel = true;\r\n codec = mediaSource.rtp[0].codec;\r\n }\r\n }\r\n\r\n if (\r\n mediaSource.type === \"application\" &&\r\n mediaSource.protocol === RTP_AVP &&\r\n mediaSource.rtp[0].codec.toLowerCase() === \"vnd.onvif.metadata\"\r\n ) {\r\n this.emit(\"log\", \"ONVIF Meta Data Found in SDP\", \"\");\r\n if (hasMetaData == false) {\r\n needSetup = true;\r\n hasMetaData = true;\r\n codec = \"vnd.onvif.metadata\";\r\n }\r\n }\r\n\r\n if (needSetup) {\r\n let streamurl = \"\";\r\n // The 'control' in the SDP can be a relative or absolute uri\r\n if (mediaSource.control) {\r\n if (mediaSource.control.toLowerCase().startsWith(\"rtsp://\")) {\r\n // absolute path\r\n streamurl = mediaSource.control;\r\n } else {\r\n // relative path\r\n streamurl = this.url + \"/\" + mediaSource.control;\r\n }\r\n }\r\n\r\n // Perform a SETUP on the streamurl\r\n // either 'udp' RTP/RTCP packets\r\n // or with 'tcp' RTP/TCP packets which are interleaved into the TCP based RTSP socket\r\n let setupRes;\r\n let rtpChannel: number;\r\n let rtcpChannel: number;\r\n let rtpReceiver: dgram.Socket|null = null; // UDP mode init value\r\n let rtcpReceiver: dgram.Socket|null = null; // UDP mode init value\r\n\r\n if (connection === \"udp\") {\r\n // Create a pair of UDP listeners, even numbered port for RTP\r\n // and odd numbered port for RTCP\r\n\r\n rtpChannel = this.nextFreeUDPPort;\r\n rtcpChannel = this.nextFreeUDPPort + 1;\r\n this.nextFreeUDPPort += 2;\r\n\r\n const rtpPort = rtpChannel;\r\n rtpReceiver = dgram.createSocket(\"udp4\");\r\n\r\n rtpReceiver.on(\"message\", (buf) => {\r\n const packet = parseRTPPacket(buf);\r\n\r\n // Add wall clock time\r\n const detail = this.setupResult.find(item => item.rtpChannel == rtpChannel);\r\n if (detail != undefined) packet.wallclockTime = this.GetWallClockTime(packet, detail);\r\n\r\n this.emit(\"data\", rtpPort, packet.payload, packet);\r\n });\r\n\r\n const rtcpPort = rtcpChannel;\r\n rtcpReceiver = dgram.createSocket(\"udp4\");\r\n\r\n rtcpReceiver.on(\"message\", (buf, remote) => {\r\n const packet = parseRTCPPacket(buf);\r\n\r\n // If this is a Sender Report, cache the NTP Wall Clock data\r\n if (packet.packetType == 200 && packet.senderReport != undefined) {\r\n const detail = this.setupResult.find(item => item.rtcpChannel == rtcpChannel);\r\n if (detail != undefined) {\r\n detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW;\r\n detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW;\r\n detail.sr_rtptimestamp = packet.senderReport.rtpTimestamp;\r\n }\r\n }\r\n\r\n this.emit(\"controlData\", rtcpPort, packet);\r\n\r\n const receiver_report = this.emptyReceiverReport();\r\n this.sendUDPData(remote.address, remote.port, receiver_report);\r\n });\r\n\r\n // Block until both UDP sockets are open.\r\n\r\n await new Promise((resolve) => {\r\n rtpReceiver?.bind(rtpPort, () => resolve({}));\r\n });\r\n\r\n await new Promise((resolve) => {\r\n rtcpReceiver?.bind(rtcpPort, () => resolve({}));\r\n });\r\n\r\n const setupHeader = {\r\n Transport: `RTP/AVP;unicast;client_port=${rtpPort}-${rtcpPort}`,\r\n };\r\n if (this.session)\r\n Object.assign(setupHeader, { Session: this.session });\r\n setupRes = await this.request(\"SETUP\", setupHeader, streamurl);\r\n } else if (connection === \"tcp\") {\r\n // channel 0, RTP\r\n // channel 1, RTCP\r\n\r\n rtpChannel = this.nextFreeInterleavedChannel;\r\n rtcpChannel = this.nextFreeInterleavedChannel + 1;\r\n this.nextFreeInterleavedChannel += 2;\r\n\r\n const setupHeader = {\r\n Transport: `RTP/AVP/TCP;interleaved=${rtpChannel}-${rtcpChannel}`,\r\n };\r\n if (this.session)\r\n Object.assign(setupHeader, { Session: this.session }); // not used on first SETUP\r\n setupRes = await this.request(\"SETUP\", setupHeader, streamurl);\r\n } else {\r\n throw new Error(\r\n `Connection parameter to RTSPClient#connect is ${connection}, not udp or tcp!`\r\n );\r\n }\r\n\r\n if (!setupRes) {\r\n throw new Error(\r\n \"No SETUP response; RTSP server is broken (sanity check)\"\r\n );\r\n }\r\n\r\n const { headers } = setupRes;\r\n\r\n if (!headers.Transport) {\r\n throw new Error(\r\n \"No Transport header on SETUP; RTSP server is broken (sanity check)\"\r\n );\r\n }\r\n\r\n const transport = parseTransport(headers.Transport);\r\n if (\r\n transport.protocol !== \"RTP/AVP/TCP\" &&\r\n transport.protocol !== \"RTP/AVP\"\r\n ) {\r\n throw new Error(\r\n \"Only RTSP servers supporting RTP/AVP(unicast) or RTP/AVP/TCP are supported at this time.\"\r\n );\r\n }\r\n\r\n // Patch from zoolyka (Zoltan Hajdu).\r\n // Try to open a hole in the NAT router (to allow incoming UDP packets)\r\n // by send a UDP packet for RTP and RTCP to the remote RTSP server.\r\n // Note, Roger did not have a router that needed this so the feature is untested.\r\n // May be better to change the RTCP message to a Receiver Report, leaving the RTP message as zero bytes\r\n if (connection === \"udp\" && transport && rtpReceiver && rtcpReceiver) {\r\n rtpReceiver.send(Buffer.from(''), Number(transport.parameters[\"server_port\"].split(\"-\")[0]), hostname);\r\n rtcpReceiver.send(Buffer.from(''), Number(transport.parameters[\"server_port\"].split(\"-\")[1]), hostname);\r\n }\r\n\r\n if (headers.Unsupported) {\r\n this.unsupportedExtensions = headers.Unsupported.split(\",\");\r\n }\r\n\r\n if (headers.Session) {\r\n this.session = headers.Session.split(\";\")[0];\r\n }\r\n\r\n const detail: Detail = {\r\n codec,\r\n mediaSource,\r\n transport: transport.parameters,\r\n isH264: codec === \"H264\", // legacy API\r\n rtpChannel,\r\n rtcpChannel,\r\n };\r\n\r\n details.push(detail);\r\n } // end if (needSetup)\r\n } // end for loop, looping over each media stream\r\n\r\n if (keepAlive) {\r\n // Start a Timer to send OPTIONS every 20 seconds to keep stream alive\r\n // using the Session ID\r\n this.keepAliveID = setInterval(() => {\r\n this.request(\"OPTIONS\", { Session: this.session });\r\n // this.request(\"OPTIONS\");\r\n }, 20 * 1000);\r\n }\r\n\r\n this.setupResult = details;\r\n return details;\r\n }\r\n\r\n request(\r\n requestName: string,\r\n headersParam: Headers = {},\r\n url?: string\r\n ): Promise<{ headers: Headers; mediaHeaders?: string[] } | void> {\r\n if (!this.client) {\r\n return Promise.resolve();\r\n }\r\n\r\n const id = ++this.cSeq;\r\n // mutable via string addition\r\n let req = `${requestName} ${url || this.url} RTSP/1.0\\r\\nCSeq: ${id}\\r\\n`;\r\n\r\n const headers = {\r\n ...this.headers,\r\n ...headersParam,\r\n };\r\n\r\n // NOTE:\r\n // If we cache the Authenitcation Type (Direct or Basic) then we could\r\n // re-compute an Authorization Header here and include in the RTSP Command\r\n // This would make connections a faster with fewer round-trips to the RTSP Server\r\n\r\n req += Object.entries(headers)\r\n .map(([key, value]) => `${key}: ${value}\\r\\n`)\r\n .join(\"\");\r\n\r\n this.emit(\"log\", req, \"C->S\");\r\n // Make sure to add an empty line after the request.\r\n this.client.write(`${req}\\r\\n`);\r\n\r\n return new Promise((resolve, reject) => {\r\n const responseHandler = (\r\n responseName: string,\r\n resHeaders: Headers,\r\n mediaHeaders: string[]\r\n ) => {\r\n const firstAnswer: string = String(resHeaders[\"\"]) || \"\";\r\n if (firstAnswer.indexOf(\"401\") >= 0 && 'Authorization' in headers) {\r\n // If the RTSP Command we sent included an Authorization and we have 401 error, then reject()\r\n reject(new Error(`Bad RTSP credentials!`));\r\n return;\r\n }\r\n if (resHeaders.CSeq !== id) {\r\n return;\r\n }\r\n\r\n this.removeListener(\"response\", responseHandler);\r\n\r\n const statusCode = parseInt(responseName.split(\" \")[1]);\r\n\r\n if (statusCode === STATUS_OK) {\r\n if (mediaHeaders.length > 0) {\r\n resolve({\r\n headers: resHeaders,\r\n mediaHeaders,\r\n });\r\n } else {\r\n resolve({\r\n headers: resHeaders,\r\n });\r\n }\r\n } else {\r\n const authHeader = resHeaders[WWW_AUTH];\r\n\r\n // We have status code unauthenticated.\r\n if (statusCode === STATUS_UNAUTH && authHeader) {\r\n const type = authHeader.split(\" \")[0];\r\n\r\n // Get auth properties from WWW_AUTH header.\r\n let realm = \"\";\r\n let nonce = \"\";\r\n let algorithm = \"MD5\"; // Default to MD5 if no algorthm is given. Milestone's RTSP server also supports SHA-256 for FIPS\r\n\r\n let match = WWW_AUTH_REGEX.exec(authHeader);\r\n while (match != null) {\r\n const prop = match[1];\r\n\r\n if (prop == \"realm\" && match[2]) {\r\n realm = match[2];\r\n }\r\n\r\n if (prop == \"nonce\" && match[2]) {\r\n nonce = match[2];\r\n }\r\n\r\n if (prop == \"algorithm\" && match[2]) {\r\n algorithm = match[2];\r\n }\r\n\r\n match = WWW_AUTH_REGEX.exec(authHeader);\r\n }\r\n\r\n // mutable, corresponds to Authorization header\r\n let authString = \"\";\r\n\r\n if (type === \"Digest\") {\r\n // Digest Authentication\r\n\r\n // Select Hash Function, default to MD5\r\n const HashFunction = (algorithm == \"SHA-256\" ? getSHA256Hash : getMD5Hash);\r\n\r\n const ha1 = HashFunction(\r\n `${this.username}:${realm}:${this.password}`\r\n );\r\n const ha2 = HashFunction(`${requestName}:${this.url}`);\r\n const ha3 = HashFunction(`${ha1}:${nonce}:${ha2}`);\r\n\r\n // Some RTSP servers to not accept \"algorithm=NNN\" in the authString and reject the authentication. So only add algorithm=ZZZZ when not using MD5\r\n if (algorithm == \"MD5\")\r\n authString = `Digest username=\"${this.username}\",realm=\"${realm}\",nonce=\"${nonce}\",uri=\"${this.url}\",response=\"${ha3}\"`;\r\n else\r\n authString = `Digest username=\"${this.username}\",realm=\"${realm}\",nonce=\"${nonce}\",algorithm=${algorithm},uri=\"${this.url}\",response=\"${ha3}\"`;\r\n } else if (type === \"Basic\") {\r\n // Basic Authentication\r\n // https://xkcd.com/538/\r\n const b64 = Buffer.from(\r\n `${this.username}:${this.password}`\r\n ).toString(\"base64\");\r\n authString = `Basic ${b64}`;\r\n }\r\n\r\n Object.assign(headers, {\r\n Authorization: authString,\r\n });\r\n\r\n resolve(this.request(requestName, headers, url)); // Call this.request with Authorized request\r\n return;\r\n }\r\n\r\n reject(new Error(`Bad RTSP status code ${statusCode}!`));\r\n return;\r\n }\r\n };\r\n\r\n this.on(\"response\", responseHandler);\r\n });\r\n }\r\n\r\n respond(status: string, headersParam: Headers = {}): void {\r\n if (!this.client) {\r\n return;\r\n }\r\n\r\n // mutable via string addition\r\n let res = `RTSP/1.0 ${status}\\r\\n`;\r\n\r\n const headers = {\r\n ...this.headers,\r\n ...headersParam,\r\n };\r\n\r\n res += Object.entries(headers)\r\n .map(([key, value]) => `${key}: ${value}\\r\\n`)\r\n .join(\"\");\r\n\r\n this.emit(\"log\", res, \"C->S\");\r\n this.client.write(`${res}\\r\\n`);\r\n }\r\n\r\n async play(): Promise {\r\n if (!this.isConnected) {\r\n throw new Error(\"Client is not connected.\");\r\n }\r\n\r\n await this.request(\"PLAY\", { Session: this.session });\r\n }\r\n\r\n async pause(): Promise {\r\n if (!this.isConnected) {\r\n throw new Error(\"Client is not connected.\");\r\n }\r\n\r\n await this.request(\"PAUSE\", { Session: this.session });\r\n }\r\n\r\n async sendAudioBackChannel(audioChunk: Buffer): Promise {\r\n let rtp, buf;\r\n const bufSize = 160;\r\n while (audioChunk.length > 0) {\r\n if (audioChunk.length > bufSize) {\r\n buf = audioChunk.slice(0, bufSize);\r\n audioChunk = audioChunk.slice(bufSize, audioChunk.length);\r\n } else {\r\n buf = audioChunk.slice(0, audioChunk.length);\r\n audioChunk = Buffer.from([]);\r\n }\r\n if (!rtp)\r\n rtp = new RTPPacket(buf);\r\n else\r\n rtp.payload = buf;\r\n // rtp.type = 8;// set động\r\n rtp.time += buf.length;\r\n rtp.seq++;\r\n const bufferLength = Buffer.alloc(2);\r\n bufferLength.writeUInt16BE(rtp.packet.length, 0);\r\n let channelInterleaved = this.setupResult.filter((value) => {\r\n return value.mediaSource.type === 'audio' && value.mediaSource.direction === 'sendonly';\r\n })[0].transport.interleaved;\r\n /* RTSP Interleaved Frame structure\r\n |dollar sign|channel identifier|data length|\r\n |1 Byte |1 Byte |2 Bytes |\r\n */\r\n channelInterleaved = channelInterleaved.split('-')[0];\r\n let interleavedHeader = Buffer.from([0x24]);// set '$'\r\n interleavedHeader = Buffer.concat([interleavedHeader, Buffer.from([channelInterleaved])]);\r\n interleavedHeader = Buffer.concat([interleavedHeader, bufferLength]);\r\n const dataToSend = Buffer.concat([interleavedHeader, rtp.packet]);\r\n await this.socketWrite(this.tcpSocket, dataToSend);\r\n }\r\n return;\r\n }\r\n\r\n async close(isImmediate = false): Promise {\r\n if (this.closed) return;\r\n this.closed = true;\r\n\r\n if (!this.client) {\r\n return;\r\n }\r\n\r\n if (!isImmediate) {\r\n await this.request(\"TEARDOWN\", {\r\n Session: this.session,\r\n });\r\n }\r\n\r\n this.client.end();\r\n this.removeAllListeners(\"response\");\r\n\r\n if (this.keepAliveID != undefined) {\r\n clearInterval(this.keepAliveID);\r\n this.keepAliveID = undefined;\r\n }\r\n\r\n this.isConnected = false;\r\n this.cSeq = 0;\r\n }\r\n\r\n private onData(data: Buffer): void {\r\n let index = 0;\r\n\r\n // $\r\n const PACKET_START = 0x24;\r\n // R\r\n const RTSP_HEADER_START = 0x52;\r\n // /n\r\n const ENDL = 10;\r\n\r\n while (index < data.length) {\r\n // read RTP or RTCP packet\r\n if (\r\n this.readState == ReadStates.SEARCHING &&\r\n data[index] == PACKET_START\r\n ) {\r\n this.messageBytes = [data[index]];\r\n index++;\r\n\r\n this.readState = ReadStates.READING_RAW_PACKET_SIZE;\r\n } else if (this.readState == ReadStates.READING_RAW_PACKET_SIZE) {\r\n // accumulate bytes for $, channel and length\r\n this.messageBytes.push(data[index]);\r\n index++;\r\n\r\n if (this.messageBytes.length == 4) {\r\n this.rtspPacketLength =\r\n (this.messageBytes[2] << 8) + this.messageBytes[3];\r\n\r\n if (this.rtspPacketLength > 0) {\r\n this.rtspPacket = Buffer.alloc(this.rtspPacketLength);\r\n this.rtspPacketPointer = 0;\r\n this.readState = ReadStates.READING_RAW_PACKET;\r\n } else {\r\n this.readState = ReadStates.SEARCHING;\r\n }\r\n }\r\n } else if (this.readState == ReadStates.READING_RAW_PACKET) {\r\n this.rtspPacket[this.rtspPacketPointer++] = data[index];\r\n index++;\r\n\r\n if (this.rtspPacketPointer == this.rtspPacketLength) {\r\n const packetChannel = this.messageBytes[1];\r\n if ((packetChannel & 0x01) === 0) {\r\n // even number\r\n const packet = parseRTPPacket(this.rtspPacket);\r\n\r\n // Get the Session Detail\r\n const detail = this.setupResult.find(item => item.rtpChannel == packetChannel);\r\n if (detail != undefined) packet.wallclockTime = this.GetWallClockTime(packet, detail);\r\n\r\n this.emit(\"data\", packetChannel, packet.payload, packet);\r\n }\r\n if ((packetChannel & 0x01) === 1) {\r\n // odd number\r\n const packet = parseRTCPPacket(this.rtspPacket);\r\n\r\n // If this is a Sender Report, cache the NTP Wall Clock data\r\n if (packet.packetType == 200 && packet.senderReport != undefined) {\r\n const detail = this.setupResult.find(item => item.rtcpChannel == packetChannel);\r\n if (detail != undefined) {\r\n detail.sr_ntpMSW = packet.senderReport.ntpTimestampMSW;\r\n detail.sr_ntpLSW = packet.senderReport.ntpTimestampLSW;\r\n detail.sr_rtptimestamp = packet.senderReport.rtpTimestamp;\r\n }\r\n }\r\n \r\n this.emit(\"controlData\", packetChannel, packet);\r\n\r\n const receiver_report = this.emptyReceiverReport();\r\n this.sendInterleavedData(packetChannel, receiver_report);\r\n }\r\n this.readState = ReadStates.SEARCHING;\r\n }\r\n // read response data\r\n } else if (\r\n this.readState == ReadStates.SEARCHING &&\r\n data[index] == RTSP_HEADER_START\r\n ) {\r\n // found the start of a RTSP rtsp_message\r\n this.messageBytes = [data[index]];\r\n index++;\r\n\r\n this.readState = ReadStates.READING_RTSP_HEADER;\r\n } else if (this.readState == ReadStates.READING_RTSP_HEADER) {\r\n // Reading a RTSP message.\r\n\r\n // Add character to the messageBytes\r\n // Ignore /r (13) but keep /n (10)\r\n if (data[index] != 13) {\r\n this.messageBytes.push(data[index]);\r\n }\r\n index++;\r\n\r\n // if we have two new lines back to back then we have a complete RTSP command,\r\n // note we may still need to read the Content Payload (the body) e.g. the SDP\r\n if (\r\n this.messageBytes.length >= 2 &&\r\n this.messageBytes[this.messageBytes.length - 2] == ENDL &&\r\n this.messageBytes[this.messageBytes.length - 1] == ENDL\r\n ) {\r\n // Parse the Header\r\n\r\n const text = String.fromCharCode.apply(null, this.messageBytes);\r\n const lines = text.split(\"\\n\");\r\n\r\n this.rtspContentLength = 0;\r\n this.rtspStatusLine = lines[0];\r\n this.rtspHeaders = {};\r\n\r\n lines.forEach((line) => {\r\n const indexOf = line.indexOf(\":\");\r\n\r\n if (indexOf !== line.length - 1) {\r\n const key = line.substring(0, indexOf).trim();\r\n const data = line.substring(indexOf + 1).trim();\r\n\r\n this.rtspHeaders[key] =\r\n key != \"Session\" && data.match(/^[0-9]+$/)\r\n ? parseInt(data, 10)\r\n : data;\r\n\r\n // workaround for buggy Hipcam RealServer/V1.0 camera which returns Content-length and not Content-Length\r\n if (key.toLowerCase() == \"content-length\") {\r\n this.rtspContentLength = parseInt(data, 10);\r\n }\r\n }\r\n });\r\n\r\n // if no content length, there there's no media headers\r\n // emit the message\r\n if (!this.rtspContentLength) {\r\n this.emit(\"log\", text, \"S->C\");\r\n\r\n this.emit(\"response\", this.rtspStatusLine, this.rtspHeaders, []);\r\n this.readState = ReadStates.SEARCHING;\r\n } else {\r\n this.messageBytes = [];\r\n this.readState = ReadStates.READING_RTSP_PAYLOAD;\r\n }\r\n }\r\n } else if (\r\n this.readState == ReadStates.READING_RTSP_PAYLOAD &&\r\n this.messageBytes.length < this.rtspContentLength\r\n ) {\r\n // Copy data into the RTSP payload\r\n this.messageBytes.push(data[index]);\r\n index++;\r\n\r\n if (this.messageBytes.length == this.rtspContentLength) {\r\n const text = String.fromCharCode.apply(null, this.messageBytes);\r\n const mediaHeaders = text.split(\"\\n\");\r\n\r\n // Emit the RTSP message\r\n this.emit(\r\n \"log\",\r\n String.fromCharCode.apply(null, this.messageBytes) + text,\r\n \"S->C\"\r\n );\r\n\r\n this.emit(\r\n \"response\",\r\n this.rtspStatusLine,\r\n this.rtspHeaders,\r\n mediaHeaders\r\n );\r\n this.readState = ReadStates.SEARCHING;\r\n }\r\n } else {\r\n // unexpected data\r\n throw new Error(\r\n \"Bug in RTSP data framing, please file an issue with the author with stacktrace.\"\r\n );\r\n }\r\n } // end while\r\n }\r\n\r\n private sendInterleavedData(channel: number, buffer: Buffer): void {\r\n if (!this.client) {\r\n return;\r\n }\r\n\r\n const req = `${buffer.length} bytes of interleaved data on channel ${channel}`;\r\n this.emit(\"log\", req, \"C->S\");\r\n\r\n const header = Buffer.alloc(4);\r\n header[0] = 0x24; // ascii $\r\n header[1] = channel;\r\n header[2] = (buffer.length >> 8) & 0xff;\r\n header[3] = (buffer.length >> 0) & 0xff;\r\n\r\n const data = Buffer.concat([header, buffer]);\r\n this.client.write(data);\r\n }\r\n\r\n private sendUDPData(host: string, port: number, buffer: Buffer): void {\r\n const udp = dgram.createSocket(\"udp4\");\r\n udp.send(buffer, 0, buffer.length, port, host, (_err, _bytes) => {\r\n // TODO: Don't ignore errors.\r\n udp.close();\r\n });\r\n }\r\n\r\n private emptyReceiverReport(): Buffer {\r\n const report = Buffer.alloc(8);\r\n const version = 2;\r\n const paddingBit = 0;\r\n const reportCount = 0; // an empty report\r\n const packetType = 201; // Receiver Report\r\n const length = report.length / 4 - 1; // num 32 bit words minus 1\r\n report[0] = (version << 6) + (paddingBit << 5) + reportCount;\r\n report[1] = packetType;\r\n report[2] = (length >> 8) & 0xff;\r\n report[3] = (length >> 0) & 0xff;\r\n report[4] = (this.clientSSRC >> 24) & 0xff;\r\n report[5] = (this.clientSSRC >> 16) & 0xff;\r\n report[6] = (this.clientSSRC >> 8) & 0xff;\r\n report[7] = (this.clientSSRC >> 0) & 0xff;\r\n\r\n return report;\r\n }\r\n\r\n private async socketWrite(socket: SocketUnion, data: Buffer): Promise {\r\n return new Promise((resolve, reject) => {\r\n setTimeout(() => {\r\n socket.write(data, (error: Error | null) => {\r\n if (error) {\r\n reject(error);\r\n } else {\r\n resolve(undefined);\r\n }\r\n })\r\n }, 20);\r\n })\r\n }\r\n\r\n ntpBaseDate_ms = new Date(\"1900/1/1\").getTime();\r\n\r\n // Note we have had a RTP Packet in Yellowstone for many years, but the Audio Backchennal code added another object also called RTPPacket\r\n GetWallClockTime(packet: util.RTPPacket, detail: Detail): Date | undefined {\r\n\r\n // Add Wall Clock Time\r\n if (detail.sr_ntpMSW != undefined && detail.sr_ntpLSW != undefined && detail.sr_rtptimestamp != undefined && detail.mediaSource.rtp[0].rate != undefined) {\r\n const refTimestampSecs = detail.sr_rtptimestamp / detail.mediaSource.rtp[0].rate; // H264 is 90 kHz clock rate\r\n const packetTimestampSecs = packet.timestamp / detail.mediaSource.rtp[0].rate; // eg 90kHz\r\n const packetTimestampDeltaSecs = packetTimestampSecs - refTimestampSecs;\r\n const refTimestamp = new Date(this.ntpBaseDate_ms + (detail.sr_ntpMSW * 1000) + ((detail.sr_ntpLSW/Math.pow(2,32))*1000));\r\n const wallclockTime = new Date(refTimestamp.getTime() + (packetTimestampDeltaSecs*1000));\r\n return wallclockTime;\r\n }\r\n\r\n // Could not generate a Wall Clock Time\r\n return undefined;\r\n }\r\n\r\n}\r\n\r\nexport { RTPPacket, RTCPPacket } from \"./util\";\r\n"]} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 5fc566a..4f824ce 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,8 +1,9 @@ import H264Transport from "./transports/H264Transport"; import H265Transport from "./transports/H265Transport"; +import AV1Transport from "./transports/AV1Transport"; import AACTransport from "./transports/AACTransport"; import ONVIFMetadataTransport from "./transports/ONVIFMetadataTransport"; import ONVIFClient from "./ONVIFClient"; import RTSPClient from "./RTSPClient"; import { RTPPacket, RTCPPacket } from "./util"; -export { H264Transport, H265Transport, AACTransport, ONVIFMetadataTransport, ONVIFClient, RTSPClient, RTPPacket, RTCPPacket }; +export { H264Transport, H265Transport, AV1Transport, AACTransport, ONVIFMetadataTransport, ONVIFClient, RTSPClient, RTPPacket, RTCPPacket }; diff --git a/dist/index.js b/dist/index.js index 5249422..914fd4c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,10 +1,12 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.RTSPClient = exports.ONVIFClient = exports.ONVIFMetadataTransport = exports.AACTransport = exports.H265Transport = exports.H264Transport = void 0; +exports.RTSPClient = exports.ONVIFClient = exports.ONVIFMetadataTransport = exports.AACTransport = exports.AV1Transport = exports.H265Transport = exports.H264Transport = void 0; const H264Transport_1 = require("./transports/H264Transport"); exports.H264Transport = H264Transport_1.default; const H265Transport_1 = require("./transports/H265Transport"); exports.H265Transport = H265Transport_1.default; +const AV1Transport_1 = require("./transports/AV1Transport"); +exports.AV1Transport = AV1Transport_1.default; const AACTransport_1 = require("./transports/AACTransport"); exports.AACTransport = AACTransport_1.default; const ONVIFMetadataTransport_1 = require("./transports/ONVIFMetadataTransport"); diff --git a/dist/index.js.map b/dist/index.js.map index 75b6c7b..e6ebd65 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,8DAAuD;AASrD,wBATK,uBAAa,CASL;AARf,8DAAuD;AASrD,wBATK,uBAAa,CASL;AARf,4DAAqD;AASnD,uBATK,sBAAY,CASL;AARd,gFAAyE;AASvE,iCATK,gCAAsB,CASL;AARxB,+CAAwC;AAStC,sBATK,qBAAW,CASL;AARb,6CAAsC;AASpC,qBATK,oBAAU,CASL","sourcesContent":["import H264Transport from \"./transports/H264Transport\";\nimport H265Transport from \"./transports/H265Transport\";\nimport AACTransport from \"./transports/AACTransport\";\nimport ONVIFMetadataTransport from \"./transports/ONVIFMetadataTransport\";\nimport ONVIFClient from \"./ONVIFClient\";\nimport RTSPClient from \"./RTSPClient\";\nimport {RTPPacket, RTCPPacket} from \"./util\";\n\nexport {\n H264Transport,\n H265Transport,\n AACTransport,\n ONVIFMetadataTransport,\n ONVIFClient,\n RTSPClient,\n RTPPacket,\n RTCPPacket\n}\n"]} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,8DAAuD;AAUrD,wBAVK,uBAAa,CAUL;AATf,8DAAuD;AAUrD,wBAVK,uBAAa,CAUL;AATf,4DAAqD;AAUnD,uBAVK,sBAAY,CAUL;AATd,4DAAqD;AAUnD,uBAVK,sBAAY,CAUL;AATd,gFAAyE;AAUvE,iCAVK,gCAAsB,CAUL;AATxB,+CAAwC;AAUtC,sBAVK,qBAAW,CAUL;AATb,6CAAsC;AAUpC,qBAVK,oBAAU,CAUL","sourcesContent":["import H264Transport from \"./transports/H264Transport\";\nimport H265Transport from \"./transports/H265Transport\";\nimport AV1Transport from \"./transports/AV1Transport\";\nimport AACTransport from \"./transports/AACTransport\";\nimport ONVIFMetadataTransport from \"./transports/ONVIFMetadataTransport\";\nimport ONVIFClient from \"./ONVIFClient\";\nimport RTSPClient from \"./RTSPClient\";\nimport {RTPPacket, RTCPPacket} from \"./util\";\n\nexport {\n H264Transport,\n H265Transport,\n AV1Transport,\n AACTransport,\n ONVIFMetadataTransport,\n ONVIFClient,\n RTSPClient,\n RTPPacket,\n RTCPPacket\n}\n"]} \ No newline at end of file diff --git a/dist/transports/AACTransport.js b/dist/transports/AACTransport.js index 6bdbfc6..d8b0c07 100644 --- a/dist/transports/AACTransport.js +++ b/dist/transports/AACTransport.js @@ -59,7 +59,7 @@ class AACTransport { ptr += 2; // Examine the AU Header. Get the size of the AAC data const aac_frame_size = ((rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0)) >> 3; // 13 bits - const aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits + const _aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits ptr += au_headers_length; // extract the AAC block if (ptr + aac_frame_size > rtp_payload.length) diff --git a/dist/transports/AACTransport.js.map b/dist/transports/AACTransport.js.map index a18fe05..45cabef 100644 --- a/dist/transports/AACTransport.js.map +++ b/dist/transports/AACTransport.js.map @@ -1 +1 @@ -{"version":3,"file":"AACTransport.js","sourceRoot":"","sources":["../../lib/transports/AACTransport.ts"],"names":[],"mappings":"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","sourcesContent":["// De-packetize RTP packets to re-create AAC High Bit Rate (hbr) Audio\n// Write Audio to a .aac file\n// By Roger Hardiman, October 2019\n\nimport RTSPClient from \"../RTSPClient\";\nimport { RTPPacket, BitStream } from \"../util\";\n\nimport * as transform from \"sdp-transform\";\nimport { Writable } from \"stream\";\n\ninterface Details {\n codec: string;\n mediaSource: transform.MediaDescription;\n rtpChannel: number;\n rtcpChannel: number;\n}\n\nexport default class AACTransport {\n client: RTSPClient;\n stream: Writable;\n\n ObjectType = 0;\n FrequencyIndex = 0;\n ChannelConfiguration = 0;\n\n constructor(client: RTSPClient, stream: Writable, details: Details) {\n this.client = client;\n this.stream = stream;\n\n client.on(\"data\", (channel, data, packet) => {\n if (channel == details.rtpChannel) {\n this.processRTPPacket(packet);\n }\n });\n\n // Process the SDP to get the parameters for the AAC audio\n // \"profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1490\"\n const fmtp = details.mediaSource.fmtp[0];\n const fmtpConfig = transform.parseParams(fmtp.config);\n\n const bs = new BitStream();\n bs.AddHexString(fmtpConfig[\"config\"].toString());\n\n /***\n 5 bits: object type\n if (object type == 31)\n 6 bits + 32: object type\n 4 bits: frequency index\n if (frequency index == 15)\n 24 bits: frequency\n 4 bits: channel configuration\n var bits: AOT Specific Config\n ***/\n\n // Read 5 bits\n this.ObjectType = bs.Read(5);\n\n // Read 4 bits\n this.FrequencyIndex = bs.Read(4);\n\n // Read 4 bits\n this.ChannelConfiguration = bs.Read(4);\n }\n\n processRTPPacket(packet: RTPPacket): void {\n // RTP Payload for MPEG4-GENERIC consis of multiple blocks of data\n\n // Each block has 3 parts\n // Part 1 - Acesss Unit Header Length + Header\n // Part 2 - Access Unit Auxiliary Data Length + Data (not used in AAC High Bitrate)\n // Part 3 - Access Unit Audio Data\n\n const rtp_payload = packet.payload;\n let ptr = 0;\n const audio_data = [];\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (ptr + 4 > rtp_payload.length) break; // 2 bytes for AU Header Length, 2 bytes of AU Header payload\n\n // Get Size of the AU Header\n const au_headers_length_bits =\n (rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0); // 16 bits\n const au_headers_length = Math.ceil(au_headers_length_bits / 8.0);\n ptr += 2;\n\n // Examine the AU Header. Get the size of the AAC data\n const aac_frame_size =\n ((rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0)) >> 3; // 13 bits\n const aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits\n ptr += au_headers_length;\n\n // extract the AAC block\n if (ptr + aac_frame_size > rtp_payload.length) break; // not enough data to copy\n audio_data.push(rtp_payload.slice(ptr, ptr + aac_frame_size));\n ptr += aac_frame_size;\n }\n\n // Write Audio Data Transport Stream (adts) header\n // followed by the AAC data\n for (let x = 0; x < audio_data.length; x++) {\n const data = audio_data[x];\n\n const bs = new BitStream(); //TODO - we could cache the header bitstream\n\n bs.AddValue(0xfff, 12); // (a) Start of data\n bs.AddValue(0, 1); // (b) Version ID, 0 = MPEG4\n bs.AddValue(0, 2); // (c) Layer always 2 bits set to 0\n const protection_absent = 1;\n bs.AddValue(protection_absent, 1); // (d) 1 = No CRC\n bs.AddValue(this.ObjectType - 1, 2); // (e) MPEG Object Type / Profile, minus 1\n bs.AddValue(this.FrequencyIndex, 4); // (f)\n bs.AddValue(0, 1); // (g) private bit. Always zero\n bs.AddValue(this.ChannelConfiguration, 3); // (h)\n bs.AddValue(0, 1); // (i) originality\n bs.AddValue(0, 1); // (j) home\n bs.AddValue(0, 1); // (k) copyrighted id\n bs.AddValue(0, 1); // (l) copyright id start\n bs.AddValue(data.length + 7, 13); // (m) AAC data + size of the ASDT header\n bs.AddValue(2047, 11); // (n) buffer fullness ???\n const num_acc_frames = 1;\n bs.AddValue(num_acc_frames - 1, 1); // (o) num of AAC Frames, minus 1\n\n // TODO If Protection was On [value=0], there would be a 16 bit CRC here\n // if (protection_absent == 0) bs.AddValue(/*Calc CRC()*/, 16); // (p)\n\n const header = bs.ToArray();\n\n // write to the aac file\n this.stream.write(header);\n this.stream.write(data);\n }\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"AACTransport.js","sourceRoot":"","sources":["../../lib/transports/AACTransport.ts"],"names":[],"mappings":"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","sourcesContent":["// De-packetize RTP packets to re-create AAC High Bit Rate (hbr) Audio\r\n// Write Audio to a .aac file\r\n// By Roger Hardiman, October 2019\r\n\r\nimport RTSPClient from \"../RTSPClient\";\r\nimport { RTPPacket, BitStream } from \"../util\";\r\n\r\nimport * as transform from \"sdp-transform\";\r\nimport { Writable } from \"stream\";\r\n\r\ninterface Details {\r\n codec: string;\r\n mediaSource: transform.MediaDescription;\r\n rtpChannel: number;\r\n rtcpChannel: number;\r\n}\r\n\r\nexport default class AACTransport {\r\n client: RTSPClient;\r\n stream: Writable;\r\n\r\n ObjectType = 0;\r\n FrequencyIndex = 0;\r\n ChannelConfiguration = 0;\r\n\r\n constructor(client: RTSPClient, stream: Writable, details: Details) {\r\n this.client = client;\r\n this.stream = stream;\r\n\r\n client.on(\"data\", (channel, data, packet) => {\r\n if (channel == details.rtpChannel) {\r\n this.processRTPPacket(packet);\r\n }\r\n });\r\n\r\n // Process the SDP to get the parameters for the AAC audio\r\n // \"profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1490\"\r\n const fmtp = details.mediaSource.fmtp[0];\r\n const fmtpConfig = transform.parseParams(fmtp.config);\r\n\r\n const bs = new BitStream();\r\n bs.AddHexString(fmtpConfig[\"config\"].toString());\r\n\r\n /***\r\n 5 bits: object type\r\n if (object type == 31)\r\n 6 bits + 32: object type\r\n 4 bits: frequency index\r\n if (frequency index == 15)\r\n 24 bits: frequency\r\n 4 bits: channel configuration\r\n var bits: AOT Specific Config\r\n ***/\r\n\r\n // Read 5 bits\r\n this.ObjectType = bs.Read(5);\r\n\r\n // Read 4 bits\r\n this.FrequencyIndex = bs.Read(4);\r\n\r\n // Read 4 bits\r\n this.ChannelConfiguration = bs.Read(4);\r\n }\r\n\r\n processRTPPacket(packet: RTPPacket): void {\r\n // RTP Payload for MPEG4-GENERIC consis of multiple blocks of data\r\n\r\n // Each block has 3 parts\r\n // Part 1 - Acesss Unit Header Length + Header\r\n // Part 2 - Access Unit Auxiliary Data Length + Data (not used in AAC High Bitrate)\r\n // Part 3 - Access Unit Audio Data\r\n\r\n const rtp_payload = packet.payload;\r\n let ptr = 0;\r\n const audio_data = [];\r\n\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n if (ptr + 4 > rtp_payload.length) break; // 2 bytes for AU Header Length, 2 bytes of AU Header payload\r\n\r\n // Get Size of the AU Header\r\n const au_headers_length_bits =\r\n (rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0); // 16 bits\r\n const au_headers_length = Math.ceil(au_headers_length_bits / 8.0);\r\n ptr += 2;\r\n\r\n // Examine the AU Header. Get the size of the AAC data\r\n const aac_frame_size =\r\n ((rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0)) >> 3; // 13 bits\r\n const _aac_index_delta = rtp_payload[ptr + 1] & 0x03; // 3 bits\r\n ptr += au_headers_length;\r\n\r\n // extract the AAC block\r\n if (ptr + aac_frame_size > rtp_payload.length) break; // not enough data to copy\r\n audio_data.push(rtp_payload.slice(ptr, ptr + aac_frame_size));\r\n ptr += aac_frame_size;\r\n }\r\n\r\n // Write Audio Data Transport Stream (adts) header\r\n // followed by the AAC data\r\n for (let x = 0; x < audio_data.length; x++) {\r\n const data = audio_data[x];\r\n\r\n const bs = new BitStream(); //TODO - we could cache the header bitstream\r\n\r\n bs.AddValue(0xfff, 12); // (a) Start of data\r\n bs.AddValue(0, 1); // (b) Version ID, 0 = MPEG4\r\n bs.AddValue(0, 2); // (c) Layer always 2 bits set to 0\r\n const protection_absent = 1;\r\n bs.AddValue(protection_absent, 1); // (d) 1 = No CRC\r\n bs.AddValue(this.ObjectType - 1, 2); // (e) MPEG Object Type / Profile, minus 1\r\n bs.AddValue(this.FrequencyIndex, 4); // (f)\r\n bs.AddValue(0, 1); // (g) private bit. Always zero\r\n bs.AddValue(this.ChannelConfiguration, 3); // (h)\r\n bs.AddValue(0, 1); // (i) originality\r\n bs.AddValue(0, 1); // (j) home\r\n bs.AddValue(0, 1); // (k) copyrighted id\r\n bs.AddValue(0, 1); // (l) copyright id start\r\n bs.AddValue(data.length + 7, 13); // (m) AAC data + size of the ASDT header\r\n bs.AddValue(2047, 11); // (n) buffer fullness ???\r\n const num_acc_frames = 1;\r\n bs.AddValue(num_acc_frames - 1, 1); // (o) num of AAC Frames, minus 1\r\n\r\n // TODO If Protection was On [value=0], there would be a 16 bit CRC here\r\n // if (protection_absent == 0) bs.AddValue(/*Calc CRC()*/, 16); // (p)\r\n\r\n const header = bs.ToArray();\r\n\r\n // write to the aac file\r\n this.stream.write(header);\r\n this.stream.write(data);\r\n }\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/transports/AV1Transport.d.ts b/dist/transports/AV1Transport.d.ts new file mode 100644 index 0000000..b4fa7a4 --- /dev/null +++ b/dist/transports/AV1Transport.d.ts @@ -0,0 +1,24 @@ +/// +/// +import RTSPClient from "../RTSPClient"; +import { RTPPacket } from "../util"; +import * as transform from "sdp-transform"; +import { Writable } from "stream"; +interface Details { + codec: string; + mediaSource: transform.MediaDescription; + rtpChannel: number; + rtcpChannel: number; +} +export default class AV1Transport { + client: RTSPClient; + stream: Writable; + rtpPackets: Buffer[]; + waitingForSequenceHeader: boolean; + constructor(client: RTSPClient, stream: Writable, details: Details); + processConnectionDetails(details: Details): void; + processRTPPacket(packet: RTPPacket): void; + processRTPFrame(rtpPackets: Buffer[]): void; + GetOBUName(obu_type: number): string; +} +export {}; diff --git a/dist/transports/AV1Transport.js b/dist/transports/AV1Transport.js new file mode 100644 index 0000000..4d1696f --- /dev/null +++ b/dist/transports/AV1Transport.js @@ -0,0 +1,264 @@ +"use strict"; +// Handle AV1 Video +// Process SDP and RTP packets +// De-packetize RTP packets to re-create AV1 OBUs +// Write AV1 OBUs to a .obu file which can be played with "ffplay" +// +// By Roger Hardiman, May 2025 +Object.defineProperty(exports, "__esModule", { value: true }); +const transform = require("sdp-transform"); +class AV1Transport { + constructor(client, stream, details) { + this.rtpPackets = []; + this.waitingForSequenceHeader = true; // used when writing .obu file as 'ffplay' does not like it if the first OBUs are not TD then SH + this.client = client; + this.stream = stream; + // process 'fmtp' + this.processConnectionDetails(details); + client.on("data", (channel, data, packet) => { + if (channel == details.rtpChannel) { + this.processRTPPacket(packet); + } + }); + } + processConnectionDetails(details) { + // There is no Sequence Header (the extra_data / parameter set) in the SDP of AV1 + // and currently we have no use for profile, level-idx or tier + const fmtp = (details.mediaSource.fmtp)[0]; + if (!fmtp) { + return; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const fmtpConfig = transform.parseParams(fmtp.config); + /* + const _profile = fmtpConfig['profile'].toString(); + const _level_idx = fmtpConfig['level-idx'].toString(); + const _tier = fmtpConfig['tier'].toString(); + */ + } + processRTPPacket(packet) { + // Accumatate RTP packets + this.rtpPackets.push(packet.payload); + // When Marker is set to 1 pass the group of packets to processRTPFrame() + if (packet.marker == 1) { + this.processRTPFrame(this.rtpPackets); + this.rtpPackets = []; + } + } + processRTPFrame(rtpPackets) { + const obus = []; // the OBUs from the RTSP server, which normally come without their length bytes (leb128) + for (let i = 0; i < rtpPackets.length; i++) { + // The RTP packet can contain more than one OBU element + // Examine the first byte of the RTP data, the Aggregation Header. + // Z = 1 Indicates that the first OBU element in this RTP packet is a contination of the last OBU element from the last packet (ie fragmentation) + // Y = 1 Indicates that the last OBU element in this RTP packet will be fragmented and will continue in the next RTP packet (so next RTP packet will have Z=1) + // W = Number of OBU elements in this RTP Packet, or 0 if the number of OBUs is not given + // If W = 0, all OBU elements are prefixed with a LEB128 length. + // If W > 0, the OBU elements _except the last one_ have a LEB128 length prefix. Last OBU has no LEB128 length prefix. It can be computed from the RTP payload size + // N = 1 Indicates first packet of a Coded Video Sequence + // 0 1 2 3 4 5 6 7 + // +-+-+-+-+-+-+-+-+ + // |Z|Y| W |N|-|-|-| + // +-+-+-+-+-+-+-+-+ + const packet = rtpPackets[i]; + let ptr = 0; + const aggregation_header = packet[ptr]; + ptr++; + const aggregation_header_z_bit = (aggregation_header >> 7) & 0x01; + //const aggregation_header_y_bit = (aggregation_header >> 6) & 0x01; + const aggregation_header_w = (aggregation_header >> 4) & 0x03; + //const aggregation_header_n_bit = (aggregation_header >> 3) & 0x01; + /* + if (aggregation_header_z_bit == 1) { + console.log("AV1 Z Fragmentation"); + } + if (aggregation_header_y_bit == 1) { + console.log("AV1 Y Fragmentation"); + } + if (aggregation_header_n_bit == 1) { + console.log("AV1 N Bit is set"); + } + */ + let obuCount = 0; + // Loop over each OBU + while (ptr < packet.length) { + obuCount++; + // Check if the OBU element will be prefixed with a LEB128 length + let hasLeb128Prefix = false; + if (aggregation_header_w == 0) + hasLeb128Prefix = true; + if (aggregation_header_w != 0 && obuCount != aggregation_header_w) + hasLeb128Prefix = true; + let obu_element_size = 0; + if (hasLeb128Prefix) { + for (let i = 0; i < 8; i++) { // max 8 bytes + const lebByte = packet[ptr]; + ptr++; + obu_element_size = obu_element_size + ((lebByte & 0x7F) << (i * 7)); + if ((lebByte & 0x80) == 0) { + // finished + break; + } + } + } + else { + // no LEB128. Size is the remaining bytes + obu_element_size = packet.length - ptr; + } + // Extract the OBU + let obu = packet.slice(ptr, ptr + obu_element_size); + ptr = ptr + obu_element_size; + // Check Z bit. If Z = 1 we need to append the new OBU data to the Partial OBU data (fragmented data) from the last RTP packet + if (aggregation_header_z_bit == 1 && obuCount == 1) { + // Pop off the last 'partial' OBU + const lastPartialObu = obus.pop(); + if (lastPartialObu == undefined) { + // error. We do not have any partial data to append this new OBU data to so drop the new OBU. + } + else { + const combinedObuData = Buffer.concat([ + lastPartialObu, + obu + ]); + obu = combinedObuData; + } + } + // We have an OBU so store it + // Note if 'Y' is set, and we are processing the last OBU in the RTP packet, the data will be only part of the fragmented data + // but we don't check the Y bit. We rely on the Z bit being set to 1 in the next RTP packet + if (obu.length > 0) { + obus.push(obu); + } + } // Ptr now parsed all OBU elements in this RTP packet + } // end for-each RTP packet in the Frame + // Write out all the OBUs + // When we write to a File, we need to add the Temporal Delimiter (TD) + // and then the SEQUENCE_HEADER (SH) + // and then the other OBUs. + // The OBUs are modified to include a LEB128 size as required in the AV1 File Format Spec Section 5 file format + // The modification is needed as the AV1 RTSP Spec strips out the OBU lengths and replaces them with OBU Prefix lengths + // which come before the OBU instead of inside the OBU. + // There is an Annex B format that keeps the length bytes as prefixes on the OBU (instead of inside them) but I've not implemented that + // Check if this Frame includes a Sequence Header + if (this.waitingForSequenceHeader) { + for (const obu of obus) { + const obuHeader = obu[0]; + const obu_type = (obuHeader >> 3) & 0x0F; + if (obu_type == 1) { // Sequence Header + this.waitingForSequenceHeader = false; + break; + } + } + } + if (this.waitingForSequenceHeader) { + // drop this RTP frame + console.log("AV1: Waiting for Sequence Header"); + } + else { + // Write the OBUs + const temporalDelimiter = Buffer.from([0x12, 0x00]); + this.stream.write(temporalDelimiter); + for (const obu of obus) { + // Take a look at the OBU and see what it contains to verify it looks correct + // OBU Header Byte + // -------------------------------------------------------------------------------- + // | 7 | 6,5,4,3 | 2 | 1 | 0 | + // |1 bit forbidden|4 bit OBU Type|1 bit hasExtension|1 bit hasSize|1 bit reserved| + // -------------------------------------------------------------------------------- + if (obu.length > 0) { + const obuHeader = obu[0]; + //const forbidden_bit = (obuHeader >> 7) & 0x01; + const obu_type = (obuHeader >> 3) & 0x0F; + const extension_bit = (obuHeader >> 2) & 0x01; + const size_bit = (obuHeader >> 1) & 0x01; + /* + const obu_name = this.GetOBUName(obu_type); + console.log("Found AV1 OBU:" + obu_name); + + if (forbidden_bit == 1) { + console.log("OBU Forbidden Bit Error"); + } + + if (obu_name == "Reserved") { + console.log("OBU Type Error"); + } + */ + if (this.waitingForSequenceHeader) { + if (obu_type == 1) { + this.waitingForSequenceHeader = false; + // Write the First TD + } + else { + // we are still waiting so drop this OBU + console.log("AV1 file writing: Dropping OBU while waiting for Sequence Header"); + continue; + } + } + // In order to write to a .obu file, we have to ensure there is a LEB128 Size after the OBU Header Byte (and Optional Extension Byte) + // The LEB128 length gets stripped out in RTP packets + if (size_bit == 0) { + let size = 0; + if (extension_bit == 0) + size = obu.length - 1; // -1 for the OBU header + if (extension_bit == 1) + size = obu.length - 2; // -2 for the OBU header and the Header Extension Byte + // Convert the Size into a LEB128 byte sequence + const leb128_bytes = []; + while (size > 0) { + const lower_7_bits = (size & 0x7F); + if (size <= 127) { + leb128_bytes.push(lower_7_bits); // leave msbit as 0 + } + else { + leb128_bytes.push(0x80 + lower_7_bits); // set msbit to 1 + } + size = (size >> 7); + } + const leb128Buffer = Buffer.from(leb128_bytes); + // Insert the leb128 size into the OBU + const header_and_extention_len = (extension_bit == 0 ? 1 : 2); // length of header PLUS extension + // Insert the LEB128 length + const newObu = Buffer.concat([ + obu.slice(0, 0 + header_and_extention_len), + leb128Buffer, + obu.slice(header_and_extention_len, obu.length) + ]); + // Set the hasSize flag to '1' in the OBU Header + newObu[0] = newObu[0] | 0x02; + // WRITE DATA + this.stream.write(newObu); + } + else { + // This OBU came with a LEB128 length. The AV1 RTSP Spec says the RTSP server should strip them out, but this + // handles the case where a RTSP Server leaves them in + // WRITE DATA + this.stream.write(obu); + } + } + } // for-each OBU in OBUs Arrau + } + } + GetOBUName(obu_type) { + switch (obu_type) { + case 0: return "Reserved"; + case 1: return "SEQUENCE_HEADER"; + case 2: return "TEMPORAL_DELIMITER"; + case 3: return "FRAME_HEADER"; + case 4: return "TILE_GROUP"; + case 5: return "METADATA"; + case 6: return "FRAME"; + case 7: return "REDUNDANT_FRAME_HEADER"; + case 8: return "TILE_LIST"; + case 9: return "Reserved"; + case 10: return "Reserved"; + case 11: return "Reserved"; + case 12: return "Reserved"; + case 13: return "Reserved"; + case 14: return "Reserved"; + case 15: return "PADDING"; + } + return "Error getting OBU Type"; + } +} +exports.default = AV1Transport; +//# sourceMappingURL=AV1Transport.js.map \ No newline at end of file diff --git a/dist/transports/AV1Transport.js.map b/dist/transports/AV1Transport.js.map new file mode 100644 index 0000000..7b5f856 --- /dev/null +++ b/dist/transports/AV1Transport.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AV1Transport.js","sourceRoot":"","sources":["../../lib/transports/AV1Transport.ts"],"names":[],"mappings":"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","sourcesContent":["// Handle AV1 Video\n// Process SDP and RTP packets\n// De-packetize RTP packets to re-create AV1 OBUs\n// Write AV1 OBUs to a .obu file which can be played with \"ffplay\"\n//\n// By Roger Hardiman, May 2025\n\nimport RTSPClient from \"../RTSPClient\";\nimport { RTPPacket } from \"../util\";\n\nimport * as transform from \"sdp-transform\";\nimport { Writable } from \"stream\";\n\ninterface Details {\n codec: string\n mediaSource: transform.MediaDescription\n rtpChannel: number,\n rtcpChannel: number\n}\n\nexport default class AV1Transport {\n client: RTSPClient;\n stream: Writable;\n\n rtpPackets: Buffer[] = [];\n waitingForSequenceHeader = true; // used when writing .obu file as 'ffplay' does not like it if the first OBUs are not TD then SH\n\n constructor(client: RTSPClient, stream: Writable, details: Details) {\n this.client = client;\n this.stream = stream;\n\n // process 'fmtp'\n this.processConnectionDetails(details);\n\n client.on(\"data\", (channel, data, packet) => {\n if (channel == details.rtpChannel) {\n this.processRTPPacket(packet);\n }\n });\n\n }\n\n processConnectionDetails(details: Details): void {\n // There is no Sequence Header (the extra_data / parameter set) in the SDP of AV1\n // and currently we have no use for profile, level-idx or tier\n const fmtp = (details.mediaSource.fmtp)[0];\n\n if (!fmtp) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const fmtpConfig = transform.parseParams(fmtp.config);\n\n /*\n const _profile = fmtpConfig['profile'].toString();\n const _level_idx = fmtpConfig['level-idx'].toString();\n const _tier = fmtpConfig['tier'].toString();\n */\n }\n\n processRTPPacket(packet: RTPPacket): void {\n // Accumatate RTP packets\n this.rtpPackets.push(packet.payload);\n\n // When Marker is set to 1 pass the group of packets to processRTPFrame()\n if (packet.marker == 1) {\n this.processRTPFrame(this.rtpPackets);\n this.rtpPackets = [];\n }\n }\n\n processRTPFrame(rtpPackets: Buffer[]): void {\n const obus: Buffer[] = []; // the OBUs from the RTSP server, which normally come without their length bytes (leb128) \n \n for (let i = 0; i < rtpPackets.length; i++) {\n\n // The RTP packet can contain more than one OBU element\n\n // Examine the first byte of the RTP data, the Aggregation Header.\n // Z = 1 Indicates that the first OBU element in this RTP packet is a contination of the last OBU element from the last packet (ie fragmentation)\n // Y = 1 Indicates that the last OBU element in this RTP packet will be fragmented and will continue in the next RTP packet (so next RTP packet will have Z=1)\n \n // W = Number of OBU elements in this RTP Packet, or 0 if the number of OBUs is not given\n // If W = 0, all OBU elements are prefixed with a LEB128 length.\n // If W > 0, the OBU elements _except the last one_ have a LEB128 length prefix. Last OBU has no LEB128 length prefix. It can be computed from the RTP payload size\n\n // N = 1 Indicates first packet of a Coded Video Sequence\n\n // 0 1 2 3 4 5 6 7\n // +-+-+-+-+-+-+-+-+\n // |Z|Y| W |N|-|-|-|\n // +-+-+-+-+-+-+-+-+\n const packet = rtpPackets[i];\n\n let ptr = 0;\n const aggregation_header = packet[ptr];\n ptr++\n const aggregation_header_z_bit = (aggregation_header >> 7) & 0x01;\n //const aggregation_header_y_bit = (aggregation_header >> 6) & 0x01;\n const aggregation_header_w = (aggregation_header >> 4) & 0x03;\n //const aggregation_header_n_bit = (aggregation_header >> 3) & 0x01;\n\n /*\n if (aggregation_header_z_bit == 1) {\n console.log(\"AV1 Z Fragmentation\");\n }\n if (aggregation_header_y_bit == 1) {\n console.log(\"AV1 Y Fragmentation\");\n }\n if (aggregation_header_n_bit == 1) {\n console.log(\"AV1 N Bit is set\");\n }\n */\n\n let obuCount = 0;\n\n // Loop over each OBU\n while (ptr < packet.length) {\n\n obuCount++;\n\n // Check if the OBU element will be prefixed with a LEB128 length\n let hasLeb128Prefix = false;\n if (aggregation_header_w == 0) hasLeb128Prefix = true;\n if (aggregation_header_w != 0 && obuCount != aggregation_header_w) hasLeb128Prefix = true;\n\n let obu_element_size = 0;\n if (hasLeb128Prefix) {\n for (let i = 0; i < 8; i++) { // max 8 bytes\n const lebByte = packet[ptr];\n ptr++;\n\n obu_element_size = obu_element_size + ((lebByte & 0x7F) << (i * 7));\n\n if ((lebByte & 0x80) == 0) {\n // finished\n break;\n }\n }\n } else {\n // no LEB128. Size is the remaining bytes\n obu_element_size = packet.length - ptr;\n }\n\n // Extract the OBU\n let obu = packet.slice(ptr, ptr + obu_element_size);\n ptr = ptr + obu_element_size;\n\n // Check Z bit. If Z = 1 we need to append the new OBU data to the Partial OBU data (fragmented data) from the last RTP packet\n if (aggregation_header_z_bit == 1 && obuCount == 1) {\n // Pop off the last 'partial' OBU\n const lastPartialObu = obus.pop();\n if (lastPartialObu == undefined) {\n // error. We do not have any partial data to append this new OBU data to so drop the new OBU.\n } else {\n const combinedObuData = Buffer.concat([\n lastPartialObu,\n obu\n ]);\n obu = combinedObuData;\n }\n }\n\n // We have an OBU so store it\n // Note if 'Y' is set, and we are processing the last OBU in the RTP packet, the data will be only part of the fragmented data\n // but we don't check the Y bit. We rely on the Z bit being set to 1 in the next RTP packet\n if (obu.length > 0) {\n obus.push(obu);\n }\n } // Ptr now parsed all OBU elements in this RTP packet\n\n\n } // end for-each RTP packet in the Frame\n\n\n // Write out all the OBUs\n // When we write to a File, we need to add the Temporal Delimiter (TD)\n // and then the SEQUENCE_HEADER (SH)\n // and then the other OBUs.\n // The OBUs are modified to include a LEB128 size as required in the AV1 File Format Spec Section 5 file format\n // The modification is needed as the AV1 RTSP Spec strips out the OBU lengths and replaces them with OBU Prefix lengths\n // which come before the OBU instead of inside the OBU.\n // There is an Annex B format that keeps the length bytes as prefixes on the OBU (instead of inside them) but I've not implemented that\n\n // Check if this Frame includes a Sequence Header\n if (this.waitingForSequenceHeader) {\n for (const obu of obus) {\n const obuHeader = obu[0];\n const obu_type = (obuHeader >> 3) & 0x0F;\n if (obu_type == 1) { // Sequence Header\n this.waitingForSequenceHeader = false;\n break;\n }\n }\n }\n\n if (this.waitingForSequenceHeader) {\n // drop this RTP frame\n console.log(\"AV1: Waiting for Sequence Header\")\n }\n else\n {\n // Write the OBUs\n const temporalDelimiter = Buffer.from([0x12, 0x00]);\n this.stream.write(temporalDelimiter);\n \n for (const obu of obus) {\n\n // Take a look at the OBU and see what it contains to verify it looks correct\n // OBU Header Byte\n // --------------------------------------------------------------------------------\n // | 7 | 6,5,4,3 | 2 | 1 | 0 |\n // |1 bit forbidden|4 bit OBU Type|1 bit hasExtension|1 bit hasSize|1 bit reserved|\n // --------------------------------------------------------------------------------\n if (obu.length > 0) {\n const obuHeader = obu[0];\n //const forbidden_bit = (obuHeader >> 7) & 0x01;\n const obu_type = (obuHeader >> 3) & 0x0F;\n const extension_bit = (obuHeader >> 2) & 0x01;\n const size_bit = (obuHeader >> 1) & 0x01;\n\n /*\n const obu_name = this.GetOBUName(obu_type);\n console.log(\"Found AV1 OBU:\" + obu_name);\n\n if (forbidden_bit == 1) {\n console.log(\"OBU Forbidden Bit Error\");\n }\n \n if (obu_name == \"Reserved\") {\n console.log(\"OBU Type Error\");\n }\n */\n\n if (this.waitingForSequenceHeader) {\n if (obu_type == 1) {\n this.waitingForSequenceHeader = false;\n\n // Write the First TD\n\n\n } else {\n // we are still waiting so drop this OBU\n console.log(\"AV1 file writing: Dropping OBU while waiting for Sequence Header\")\n continue;\n }\n }\n \n\n // In order to write to a .obu file, we have to ensure there is a LEB128 Size after the OBU Header Byte (and Optional Extension Byte)\n // The LEB128 length gets stripped out in RTP packets\n if (size_bit == 0) {\n let size = 0;\n if (extension_bit == 0) size = obu.length - 1; // -1 for the OBU header\n if (extension_bit == 1) size = obu.length - 2; // -2 for the OBU header and the Header Extension Byte\n \n // Convert the Size into a LEB128 byte sequence\n const leb128_bytes = [];\n while (size > 0) {\n const lower_7_bits = (size & 0x7F);\n if (size <= 127) {\n leb128_bytes.push(lower_7_bits); // leave msbit as 0\n } else {\n leb128_bytes.push(0x80 + lower_7_bits); // set msbit to 1\n }\n size = (size >> 7);\n }\n const leb128Buffer = Buffer.from(leb128_bytes);\n\n // Insert the leb128 size into the OBU\n const header_and_extention_len = (extension_bit == 0 ? 1 : 2); // length of header PLUS extension\n // Insert the LEB128 length\n const newObu = Buffer.concat([\n obu.slice(0, 0 + header_and_extention_len),\n leb128Buffer,\n obu.slice(header_and_extention_len,obu.length)\n ]);\n // Set the hasSize flag to '1' in the OBU Header\n newObu[0] = newObu[0] | 0x02;\n\n // WRITE DATA\n this.stream.write(newObu);\n }\n else\n {\n // This OBU came with a LEB128 length. The AV1 RTSP Spec says the RTSP server should strip them out, but this\n // handles the case where a RTSP Server leaves them in\n // WRITE DATA\n this.stream.write(obu);\n }\n }\n } // for-each OBU in OBUs Arrau\n }\n }\n\n\n GetOBUName(obu_type: number): string {\n switch (obu_type)\n {\n case 0: return \"Reserved\";\n case 1: return \"SEQUENCE_HEADER\";\n case 2: return \"TEMPORAL_DELIMITER\";\n case 3: return \"FRAME_HEADER\";\n case 4: return \"TILE_GROUP\";\n case 5: return \"METADATA\";\n case 6: return \"FRAME\";\n case 7: return \"REDUNDANT_FRAME_HEADER\";\n case 8: return \"TILE_LIST\";\n case 9: return \"Reserved\";\n case 10: return \"Reserved\";\n case 11: return \"Reserved\";\n case 12: return \"Reserved\";\n case 13: return \"Reserved\";\n case 14: return \"Reserved\";\n case 15: return \"PADDING\";\n }\n\n return \"Error getting OBU Type\";\n }\n}\n"]} \ No newline at end of file diff --git a/dist/transports/H264Transport.js b/dist/transports/H264Transport.js index 7a9a289..dc2bdf9 100644 --- a/dist/transports/H264Transport.js +++ b/dist/transports/H264Transport.js @@ -84,7 +84,7 @@ class H264Transport { // Parse Fragmentation Unit Header const fu_header_s = (packet[1] >> 7) & 0x01; // start marker const fu_header_e = (packet[1] >> 6) & 0x01; // end marker - const fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0 + const _fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0 const fu_header_type = (packet[1] >> 0) & 0x1F; // Original NAL unit header // Check Start and End flags if (fu_header_s == 1 && fu_header_e == 0) { // Start of Fragment} diff --git a/dist/transports/H264Transport.js.map b/dist/transports/H264Transport.js.map index ea7619f..ceb2be8 100644 --- a/dist/transports/H264Transport.js.map +++ b/dist/transports/H264Transport.js.map @@ -1 +1 @@ -{"version":3,"file":"H264Transport.js","sourceRoot":"","sources":["../../lib/transports/H264Transport.ts"],"names":[],"mappings":";AAAA,8BAA8B;AAC9B,uDAAuD;AACvD,sCAAsC;;AAKtC,2CAA2C;AAG3C,oBAAoB;AACpB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,IAAI,CAAC,CAAC,CAAC;AASvD,MAAqB,aAAa;IAQhC,YAAY,MAAkB,EAAE,MAAgB,EAAE,OAAgB;QAJlE,eAAU,GAAa,EAAE,CAAC;QAE1B,mBAAc,GAAG,KAAK,CAAC;QAGrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,cAAc,EAAE;oBACvB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;iBAC/B;aACF;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,wBAAwB,CAAC,OAAgB;QACvC,2DAA2D;QAC3D,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,uBAAuB,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzF,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED,gBAAgB,CAAC,MAAiB;QAChC,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAErC,yEAAyE;QACzE,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;YACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;SACtB;IACH,CAAC;IAED,eAAe,CAAC,UAAoB;QAClC,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;YACjD,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;YAC/C,MAAM,eAAe,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;YAEhD,IAAI,eAAe,IAAI,CAAC,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,6BAA6B;gBAChF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACnB;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,2DAA2D;gBAC7F,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,iDAAiD;gBAC9D,4EAA4E;gBAC5E,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;oBACpC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBACzD,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;oBACd,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAC,GAAG,GAAC,IAAI,CAAC,CAAC,CAAC;oBACtC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;iBAClB;aACF;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,SAAS;gBAC3C,gBAAgB;aACjB;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,UAAU;gBAC5C,gBAAgB;aACjB;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,UAAU;gBAC5C,gBAAgB;aACjB;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,YAAY;gBAC9C,wCAAwC;gBACxC,uCAAuC;gBACvC,kCAAkC;gBAClC,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAE,eAAe;gBAC7D,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAE,aAAa;gBAC3D,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAE,wBAAwB;gBACtE,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,2BAA2B;gBAE3E,4BAA4B;gBAC5B,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,EAAE,qBAAqB;oBAC/D,MAAM,sBAAsB,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC;0BACtB,CAAC,cAAc,IAAI,CAAC,CAAC;0BACrB,cAAc,CAAC;oBAC/C,UAAU,GAAG,EAAE,CAAC;oBAChB,UAAU,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;oBAExC,sDAAsD;oBACtD,KAAK,IAAI,CAAC,GAAC,CAAC,EAAE,CAAC,GAAE,MAAM,CAAC,MAAM,EAAC,CAAC,EAAE;wBAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;iBAChE;gBAED,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,EAAE,2BAA2B;oBACrE,KAAK,IAAI,CAAC,GAAC,CAAC,EAAE,CAAC,GAAE,MAAM,CAAC,MAAM,EAAC,CAAC,EAAE;wBAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;iBAChE;gBAED,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,EAAE,mBAAmB;oBAC7D,KAAK,IAAI,CAAC,GAAC,CAAC,EAAE,CAAC,GAAE,MAAM,CAAC,MAAM,EAAC,CAAC,EAAE;wBAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC/D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;iBACpC;aACF;iBAAM,IAAI,eAAe,IAAI,EAAE,EAAE,EAAE,YAAY;gBAC9C,gBAAgB;aACjB;SACF;QAED,yBAAyB;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAClC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SAC9B;IACH,CAAC;CACF;AA5HD,gCA4HC","sourcesContent":["// Process SDP and RTP packets\n// De-packetize RTP packets to re-create H264 NAL Units\n// Write H264 NAL units to a .264 file\n\nimport RTSPClient from \"../RTSPClient\";\nimport {RTPPacket} from \"../util\";\n\nimport * as transform from \"sdp-transform\";\nimport { Writable } from \"stream\";\n\n// .h264 file header\nconst H264_HEADER = Buffer.from([0x00,0x00,0x00,0x01]);\n\ninterface Details {\n codec: string\n mediaSource: transform.MediaDescription\n rtpChannel: number,\n rtcpChannel: number\n}\n\nexport default class H264Transport {\n client: RTSPClient;\n stream: Writable;\n\n rtpPackets: Buffer[] = [];\n\n _headerWritten = false;\n\n constructor(client: RTSPClient, stream: Writable, details: Details) {\n this.client = client;\n this.stream = stream;\n\n client.on(\"data\", (channel, data, packet) => {\n if (channel == details.rtpChannel) {\n if (this._headerWritten) {\n this.processRTPPacket(packet);\n }\n }\n });\n\n this.processConnectionDetails(details);\n }\n\n processConnectionDetails(details: Details): void {\n // Extract SPS and PPS from the MediaSource part of the SDP\n const fmtp = (details.mediaSource.fmtp)[0];\n \n if (!fmtp) {\n return;\n }\n \n const fmtpConfig = transform.parseParams(fmtp.config);\n const splitSpropParameterSets = fmtpConfig['sprop-parameter-sets'].toString().split(',');\n const sps_base64 = splitSpropParameterSets[0];\n const pps_base64 = splitSpropParameterSets[1];\n const sps = Buffer.from(sps_base64, \"base64\");\n const pps = Buffer.from(pps_base64, \"base64\");\n\n this.stream.write(H264_HEADER);\n this.stream.write(sps);\n this.stream.write(H264_HEADER);\n this.stream.write(pps);\n\n this._headerWritten = true;\n }\n\n processRTPPacket(packet: RTPPacket): void {\n // Accumatate RTP packets\n this.rtpPackets.push(packet.payload);\n \n // When Marker is set to 1 pass the group of packets to processRTPFrame()\n if (packet.marker == 1) {\n this.processRTPFrame(this.rtpPackets);\n this.rtpPackets = [];\n }\n }\n\n processRTPFrame(rtpPackets: Buffer[]): void {\n const nals = [];\n let partialNal = [];\n\n for (let i = 0; i < rtpPackets.length; i++) {\n const packet = rtpPackets[i];\n const nal_header_f_bit = (packet[0] >> 7) & 0x01;\n const nal_header_nri = (packet[0] >> 5) & 0x03;\n const nal_header_type = (packet[0] >> 0) & 0x1F;\n\n if (nal_header_type >= 1 && nal_header_type <= 23) { // Normal NAL. Not fragmented\n nals.push(packet);\n } else if (nal_header_type == 24) { // Aggregation type STAP-A. Multiple NAls in one RTP Packet\n let ptr = 1; // start after the nal_header_type which was '24'\n // if we have at least 2 more bytes (the 16 bit size) then consume more data\n while (ptr + 2 < (packet.length - 1)) {\n const size = (packet[ptr] << 8) + (packet[ptr + 1] << 0);\n ptr = ptr + 2;\n nals.push(packet.slice(ptr,ptr+size));\n ptr = ptr + size;\n }\n } else if (nal_header_type == 25) { // STAP-B\n // Not supported\n } else if (nal_header_type == 26) { // MTAP-16\n // Not supported\n } else if (nal_header_type == 27) { // MTAP-24\n // Not supported\n } else if (nal_header_type == 28) { // Frag FU-A\n // NAL is split over several RTP packets\n // Accumulate them in a tempoary buffer\n // Parse Fragmentation Unit Header\n const fu_header_s = (packet[1] >> 7) & 0x01; // start marker\n const fu_header_e = (packet[1] >> 6) & 0x01; // end marker\n const fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0\n const fu_header_type = (packet[1] >> 0) & 0x1F; // Original NAL unit header\n\n // Check Start and End flags\n if (fu_header_s == 1 && fu_header_e == 0) { // Start of Fragment}\n const reconstructed_nal_type = (nal_header_f_bit << 7)\n + (nal_header_nri << 5)\n + fu_header_type;\n partialNal = [];\n partialNal.push(reconstructed_nal_type);\n\n // copy the rest of the RTP payload to the temp buffer\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\n }\n\n if (fu_header_s == 0 && fu_header_e == 0) { // Middle part of fragment}\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\n }\n\n if (fu_header_s == 0 && fu_header_e == 1) { // End of fragment}\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\n nals.push(Buffer.from(partialNal));\n }\n } else if (nal_header_type == 29) { // Frag FU-B\n // Not supported\n }\n }\n\n // Write out all the NALs\n for (let x = 0; x < nals.length; x++) {\n this.stream.write(H264_HEADER);\n this.stream.write(nals[x]);\n }\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"H264Transport.js","sourceRoot":"","sources":["../../lib/transports/H264Transport.ts"],"names":[],"mappings":"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","sourcesContent":["// Process SDP and RTP packets\r\n// De-packetize RTP packets to re-create H264 NAL Units\r\n// Write H264 NAL units to a .264 file\r\n\r\nimport RTSPClient from \"../RTSPClient\";\r\nimport {RTPPacket} from \"../util\";\r\n\r\nimport * as transform from \"sdp-transform\";\r\nimport { Writable } from \"stream\";\r\n\r\n// .h264 file header\r\nconst H264_HEADER = Buffer.from([0x00,0x00,0x00,0x01]);\r\n\r\ninterface Details {\r\n codec: string\r\n mediaSource: transform.MediaDescription\r\n rtpChannel: number,\r\n rtcpChannel: number\r\n}\r\n\r\nexport default class H264Transport {\r\n client: RTSPClient;\r\n stream: Writable;\r\n\r\n rtpPackets: Buffer[] = [];\r\n\r\n _headerWritten = false;\r\n\r\n constructor(client: RTSPClient, stream: Writable, details: Details) {\r\n this.client = client;\r\n this.stream = stream;\r\n\r\n client.on(\"data\", (channel, data, packet) => {\r\n if (channel == details.rtpChannel) {\r\n if (this._headerWritten) {\r\n this.processRTPPacket(packet);\r\n }\r\n }\r\n });\r\n\r\n this.processConnectionDetails(details);\r\n }\r\n\r\n processConnectionDetails(details: Details): void {\r\n // Extract SPS and PPS from the MediaSource part of the SDP\r\n const fmtp = (details.mediaSource.fmtp)[0];\r\n \r\n if (!fmtp) {\r\n return;\r\n }\r\n \r\n const fmtpConfig = transform.parseParams(fmtp.config);\r\n const splitSpropParameterSets = fmtpConfig['sprop-parameter-sets'].toString().split(',');\r\n const sps_base64 = splitSpropParameterSets[0];\r\n const pps_base64 = splitSpropParameterSets[1];\r\n const sps = Buffer.from(sps_base64, \"base64\");\r\n const pps = Buffer.from(pps_base64, \"base64\");\r\n\r\n this.stream.write(H264_HEADER);\r\n this.stream.write(sps);\r\n this.stream.write(H264_HEADER);\r\n this.stream.write(pps);\r\n\r\n this._headerWritten = true;\r\n }\r\n\r\n processRTPPacket(packet: RTPPacket): void {\r\n // Accumatate RTP packets\r\n this.rtpPackets.push(packet.payload);\r\n \r\n // When Marker is set to 1 pass the group of packets to processRTPFrame()\r\n if (packet.marker == 1) {\r\n this.processRTPFrame(this.rtpPackets);\r\n this.rtpPackets = [];\r\n }\r\n }\r\n\r\n processRTPFrame(rtpPackets: Buffer[]): void {\r\n const nals = [];\r\n let partialNal = [];\r\n\r\n for (let i = 0; i < rtpPackets.length; i++) {\r\n const packet = rtpPackets[i];\r\n const nal_header_f_bit = (packet[0] >> 7) & 0x01;\r\n const nal_header_nri = (packet[0] >> 5) & 0x03;\r\n const nal_header_type = (packet[0] >> 0) & 0x1F;\r\n\r\n if (nal_header_type >= 1 && nal_header_type <= 23) { // Normal NAL. Not fragmented\r\n nals.push(packet);\r\n } else if (nal_header_type == 24) { // Aggregation type STAP-A. Multiple NAls in one RTP Packet\r\n let ptr = 1; // start after the nal_header_type which was '24'\r\n // if we have at least 2 more bytes (the 16 bit size) then consume more data\r\n while (ptr + 2 < (packet.length - 1)) {\r\n const size = (packet[ptr] << 8) + (packet[ptr + 1] << 0);\r\n ptr = ptr + 2;\r\n nals.push(packet.slice(ptr,ptr+size));\r\n ptr = ptr + size;\r\n }\r\n } else if (nal_header_type == 25) { // STAP-B\r\n // Not supported\r\n } else if (nal_header_type == 26) { // MTAP-16\r\n // Not supported\r\n } else if (nal_header_type == 27) { // MTAP-24\r\n // Not supported\r\n } else if (nal_header_type == 28) { // Frag FU-A\r\n // NAL is split over several RTP packets\r\n // Accumulate them in a tempoary buffer\r\n // Parse Fragmentation Unit Header\r\n const fu_header_s = (packet[1] >> 7) & 0x01; // start marker\r\n const fu_header_e = (packet[1] >> 6) & 0x01; // end marker\r\n const _fu_header_r = (packet[1] >> 5) & 0x01; // reserved. should be 0\r\n const fu_header_type = (packet[1] >> 0) & 0x1F; // Original NAL unit header\r\n\r\n // Check Start and End flags\r\n if (fu_header_s == 1 && fu_header_e == 0) { // Start of Fragment}\r\n const reconstructed_nal_type = (nal_header_f_bit << 7)\r\n + (nal_header_nri << 5)\r\n + fu_header_type;\r\n partialNal = [];\r\n partialNal.push(reconstructed_nal_type);\r\n\r\n // copy the rest of the RTP payload to the temp buffer\r\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\r\n }\r\n\r\n if (fu_header_s == 0 && fu_header_e == 0) { // Middle part of fragment}\r\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\r\n }\r\n\r\n if (fu_header_s == 0 && fu_header_e == 1) { // End of fragment}\r\n for (let x=2; x< packet.length;x++) partialNal.push(packet[x]);\r\n nals.push(Buffer.from(partialNal));\r\n }\r\n } else if (nal_header_type == 29) { // Frag FU-B\r\n // Not supported\r\n }\r\n }\r\n\r\n // Write out all the NALs\r\n for (let x = 0; x < nals.length; x++) {\r\n this.stream.write(H264_HEADER);\r\n this.stream.write(nals[x]);\r\n }\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/transports/H265Transport.js b/dist/transports/H265Transport.js index 451543c..01ead75 100644 --- a/dist/transports/H265Transport.js +++ b/dist/transports/H265Transport.js @@ -65,10 +65,10 @@ class H265Transport { */ const packet = rtpPackets[i]; const payload_header = (packet[0] << 8) | (packet[1]); - const payload_header_f_bit = (payload_header >> 15) & 0x01; + const _payload_header_f_bit = (payload_header >> 15) & 0x01; const payload_header_type = (payload_header >> 9) & 0x3F; - const payload_header_layer_id = (payload_header >> 3) & 0x3F; - const payload_header_tid = payload_header & 0x7; + const _payload_header_layer_id = (payload_header >> 3) & 0x3F; + const _payload_header_tid = payload_header & 0x7; // There are three ways to Packetize NAL units into RTP Packets // Single NAL Unit Packet // Aggregation Packet (payload_header_type = 48) diff --git a/dist/transports/H265Transport.js.map b/dist/transports/H265Transport.js.map index 3620cc1..e4a1397 100644 --- a/dist/transports/H265Transport.js.map +++ b/dist/transports/H265Transport.js.map @@ -1 +1 @@ -{"version":3,"file":"H265Transport.js","sourceRoot":"","sources":["../../lib/transports/H265Transport.ts"],"names":[],"mappings":";AAAA,8BAA8B;AAC9B,uDAAuD;AACvD,sCAAsC;;AAKtC,2CAA2C;AAG3C,oBAAoB;AACpB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAS1D,MAAqB,aAAa;IAOhC,YAAY,MAAkB,EAAE,MAAgB,EAAE,OAAgB;QAJlE,aAAQ,GAAG,KAAK,CAAC;QAEjB,eAAU,GAAa,EAAE,CAAC;QAGxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,gDAAgD;QAChD,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE;gBACjC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;aAC/B;QACH,CAAC,CAAC,CAAC;IAEL,CAAC;IAED,wBAAwB,CAAC,OAAgB;QACvC,qEAAqE;QACrE,sGAAsG;QACtG,gCAAgC;QAChC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;QAEtE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,gBAAgB,CAAC,MAAiB;QAChC,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAErC,yEAAyE;QACzE,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;YACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;SACtB;IACH,CAAC;IAED,eAAe,CAAC,UAAoB;QAClC,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAE1C,kEAAkE;YAClE,qBAAqB;YACrB,sDAAsD;YACtD,UAAU;YACV,8BAA8B;YAC9B;;;;;gBAKI;YACJ,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAE7B,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,oBAAoB,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;YAC3D,MAAM,mBAAmB,GAAG,CAAC,cAAc,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;YACzD,MAAM,uBAAuB,GAAG,CAAC,cAAc,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;YAC7D,MAAM,kBAAkB,GAAG,cAAc,GAAG,GAAG,CAAC;YAEhD,+DAA+D;YAC/D,0BAA0B;YAC1B,iDAAiD;YACjD,iDAAiD;YAGjD,yBAAyB;YACzB,SAAS;YACT,SAAS;YACT,SAAS;YACT,IAAI,mBAAmB,IAAI,EAAE,IAAI,mBAAmB,IAAI,EAAE,EAAE;gBAC1D,oBAAoB;gBACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACnB;YAED,qBAAqB;iBAChB,IAAI,mBAAmB,IAAI,EAAE,EAAE;gBAClC,OAAO;gBACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;aACpB;YAGD,qBAAqB;iBAChB,IAAI,mBAAmB,IAAI,EAAE,EAAE;gBAClC,0CAA0C;gBAE1C,qBAAqB;gBACrB,sBAAsB;gBACtB,sBAAsB;gBACtB,sBAAsB;gBACvB,EAAE;gBAED,kCAAkC;gBAClC,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAE,eAAe;gBAC7D,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAE,aAAa;gBAC3D,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,UAAU;gBAE1D,wEAAwE;gBAExE,4BAA4B;gBAC5B,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE;oBACxC,kBAAkB;oBAClB,qCAAqC;oBAErC,8BAA8B;oBAC9B,UAAU,GAAG,EAAE,CAAC;oBAEhB,yFAAyF;oBACzF,IAAI,UAAU,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,4BAA4B;oBACxE,UAAU,GAAG,UAAU,GAAG,CAAC,cAAc,IAAI,CAAC,CAAC,CAAC;oBAEhD,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;oBAC1C,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;iBAC3C;gBAGD,sBAAsB;gBACtB,IAAI,IAAI,CAAC,QAAQ,EAAE;oBACjB,oCAAoC;oBACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;wBACtC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iDAAiD;qBAC9E;iBACF;qBACI;oBACH,wBAAwB;oBACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;wBACtC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iDAAiD;qBAC9E;iBACF;gBAED,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE;oBACxC,eAAe;oBACf,4CAA4C;oBAE5C,wCAAwC;oBACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;iBACpC;aACF;iBACI;gBACH,4EAA4E;aAC7E;SACF;QAED,yBAAyB;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SAC5B;IACH,CAAC;CACF;AA1KD,gCA0KC","sourcesContent":["// Process SDP and RTP packets\n// De-packetize RTP packets to re-create H265 NAL Units\n// Write H265 NAL units to a .265 file\n\nimport RTSPClient from \"../RTSPClient\";\nimport { RTPPacket } from \"../util\";\n\nimport * as transform from \"sdp-transform\";\nimport { Writable } from \"stream\";\n\n// .h265 file header\nconst H265_HEADER = Buffer.from([0x00, 0x00, 0x00, 0x01]);\n\ninterface Details {\n codec: string\n mediaSource: transform.MediaDescription\n rtpChannel: number,\n rtcpChannel: number\n}\n\nexport default class H265Transport {\n client: RTSPClient;\n stream: Writable;\n has_donl = false;\n\n rtpPackets: Buffer[] = [];\n\n constructor(client: RTSPClient, stream: Writable, details: Details) {\n this.client = client;\n this.stream = stream;\n\n // process 'fmtp' (which is optional in the SDP)\n this.processConnectionDetails(details);\n\n client.on(\"data\", (channel, data, packet) => {\n if (channel == details.rtpChannel) {\n this.processRTPPacket(packet);\n }\n });\n\n }\n\n processConnectionDetails(details: Details): void {\n // Extract the VPS, SPS and PPS from the MediaSource part of the SDP.\n // NOTE the H265 RTP standard makes this optional and we may need to extract this from the RTP payload\n // as inband VPS/SPS/PPS instead\n const fmtp = (details.mediaSource.fmtp)[0];\n\n if (!fmtp) {\n return;\n }\n\n const fmtpConfig = transform.parseParams(fmtp.config);\n const vps = Buffer.from(fmtpConfig['sprop-vps'].toString(), \"base64\");\n const sps = Buffer.from(fmtpConfig['sprop-sps'].toString(), \"base64\");\n const pps = Buffer.from(fmtpConfig['sprop-pps'].toString(), \"base64\");\n\n this.stream.write(H265_HEADER);\n this.stream.write(vps);\n this.stream.write(H265_HEADER);\n this.stream.write(sps);\n this.stream.write(H265_HEADER);\n this.stream.write(pps);\n }\n\n processRTPPacket(packet: RTPPacket): void {\n // Accumatate RTP packets\n this.rtpPackets.push(packet.payload);\n\n // When Marker is set to 1 pass the group of packets to processRTPFrame()\n if (packet.marker == 1) {\n this.processRTPFrame(this.rtpPackets);\n this.rtpPackets = [];\n }\n }\n\n processRTPFrame(rtpPackets: Buffer[]): void {\n const nals = [];\n let partialNal = [];\n\n for (let i = 0; i < rtpPackets.length; i++) {\n\n // Examine the first two bytes of the RTP data, the Payload Header\n // F (Forbidden Bit),\n // Type of NAL Unit (or VCL NAL Unit if Type is < 32),\n // LayerId\n // TID (TemporalID = TID - 1)\n /*+---------------+---------------+\n *|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|\n *+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n *|F| Type | LayerId | TID |\n *+-------------+-----------------+\n */\n const packet = rtpPackets[i];\n\n const payload_header = (packet[0] << 8) | (packet[1]);\n const payload_header_f_bit = (payload_header >> 15) & 0x01;\n const payload_header_type = (payload_header >> 9) & 0x3F;\n const payload_header_layer_id = (payload_header >> 3) & 0x3F;\n const payload_header_tid = payload_header & 0x7;\n\n // There are three ways to Packetize NAL units into RTP Packets\n // Single NAL Unit Packet\n // Aggregation Packet (payload_header_type = 48)\n // Fragmentation Unit (payload_header_type = 49)\n\n\n // Single NAL Unit Packet\n // 32=VPS\n // 33=SPS\n // 34=PPS\n if (payload_header_type != 48 && payload_header_type != 49) {\n //TODO - Handle DONL\n nals.push(packet);\n }\n\n // Aggregation Packet\n else if (payload_header_type == 48) {\n // TODO\n console.log(\"eek\");\n }\n\n\n // Fragmentation Unit\n else if (payload_header_type == 49) {\n //Console.WriteLine(\"Fragmentation Unit\");\n\n // 0 1 2 3 4 5 6 7\n // +-+-+-+-+-+-+-+-+\n // |S|E| FuType |\n // +---------------+\n //\n\n // Parse Fragmentation Unit Header\n const fu_header_s = (packet[2] >> 7) & 0x01; // start marker\n const fu_header_e = (packet[2] >> 6) & 0x01; // end marker\n const fu_header_type = (packet[2] >> 0) & 0x3F; // fu type\n\n // Console.WriteLine(\"Frag FU-A s=\" + fu_header_s + \"e=\" + fu_header_e);\n\n // Check Start and End flags\n if (fu_header_s == 1 && fu_header_e == 0) {\n // Start Fragment.\n // Initiise the partialNal byte array\n\n // Empty the partial NAL array\n partialNal = [];\n\n // Reconstrut the NAL header from the rtp_payload_header, replacing the Type with FU Type\n let nal_header = (payload_header & 0x81FF); // strip out existing 'type'\n nal_header = nal_header | (fu_header_type << 9);\n\n partialNal.push((nal_header >> 8) & 0xFF);\n partialNal.push((nal_header >> 0) & 0xFF);\n }\n\n\n // Copy the video data\n if (this.has_donl) {\n // start copying after the DONL data\n for (let x = 5; x < packet.length; x++) {\n partialNal.push(packet[x]); // not very efficient, copying one byte at a time\n }\n }\n else {\n // there is no DONL data\n for (let x = 3; x < packet.length; x++) {\n partialNal.push(packet[x]); // not very efficient, copying one byte at a time\n }\n }\n\n if (fu_header_s == 0 && fu_header_e == 1) {\n // End Fragment\n // Append this payload to the fragmented_nal\n\n // Add the NAL to the array of NAL units\n nals.push(Buffer.from(partialNal));\n }\n }\n else {\n //Console.WriteLine(\"Unknown Payload Header Type = \" + payload_header_type);\n }\n }\n\n // Write out all the NALs\n for (let x = 0; x < nals.length; x++) {\n this.stream.write(H265_HEADER);\n this.stream.write(nals[x]);\n }\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"H265Transport.js","sourceRoot":"","sources":["../../lib/transports/H265Transport.ts"],"names":[],"mappings":"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","sourcesContent":["// Process SDP and RTP packets\r\n// De-packetize RTP packets to re-create H265 NAL Units\r\n// Write H265 NAL units to a .265 file\r\n\r\nimport RTSPClient from \"../RTSPClient\";\r\nimport { RTPPacket } from \"../util\";\r\n\r\nimport * as transform from \"sdp-transform\";\r\nimport { Writable } from \"stream\";\r\n\r\n// .h265 file header\r\nconst H265_HEADER = Buffer.from([0x00, 0x00, 0x00, 0x01]);\r\n\r\ninterface Details {\r\n codec: string\r\n mediaSource: transform.MediaDescription\r\n rtpChannel: number,\r\n rtcpChannel: number\r\n}\r\n\r\nexport default class H265Transport {\r\n client: RTSPClient;\r\n stream: Writable;\r\n has_donl = false;\r\n\r\n rtpPackets: Buffer[] = [];\r\n\r\n constructor(client: RTSPClient, stream: Writable, details: Details) {\r\n this.client = client;\r\n this.stream = stream;\r\n\r\n // process 'fmtp' (which is optional in the SDP)\r\n this.processConnectionDetails(details);\r\n\r\n client.on(\"data\", (channel, data, packet) => {\r\n if (channel == details.rtpChannel) {\r\n this.processRTPPacket(packet);\r\n }\r\n });\r\n\r\n }\r\n\r\n processConnectionDetails(details: Details): void {\r\n // Extract the VPS, SPS and PPS from the MediaSource part of the SDP.\r\n // NOTE the H265 RTP standard makes this optional and we may need to extract this from the RTP payload\r\n // as inband VPS/SPS/PPS instead\r\n const fmtp = (details.mediaSource.fmtp)[0];\r\n\r\n if (!fmtp) {\r\n return;\r\n }\r\n\r\n const fmtpConfig = transform.parseParams(fmtp.config);\r\n const vps = Buffer.from(fmtpConfig['sprop-vps'].toString(), \"base64\");\r\n const sps = Buffer.from(fmtpConfig['sprop-sps'].toString(), \"base64\");\r\n const pps = Buffer.from(fmtpConfig['sprop-pps'].toString(), \"base64\");\r\n\r\n this.stream.write(H265_HEADER);\r\n this.stream.write(vps);\r\n this.stream.write(H265_HEADER);\r\n this.stream.write(sps);\r\n this.stream.write(H265_HEADER);\r\n this.stream.write(pps);\r\n }\r\n\r\n processRTPPacket(packet: RTPPacket): void {\r\n // Accumatate RTP packets\r\n this.rtpPackets.push(packet.payload);\r\n\r\n // When Marker is set to 1 pass the group of packets to processRTPFrame()\r\n if (packet.marker == 1) {\r\n this.processRTPFrame(this.rtpPackets);\r\n this.rtpPackets = [];\r\n }\r\n }\r\n\r\n processRTPFrame(rtpPackets: Buffer[]): void {\r\n const nals = [];\r\n let partialNal = [];\r\n\r\n for (let i = 0; i < rtpPackets.length; i++) {\r\n\r\n // Examine the first two bytes of the RTP data, the Payload Header\r\n // F (Forbidden Bit),\r\n // Type of NAL Unit (or VCL NAL Unit if Type is < 32),\r\n // LayerId\r\n // TID (TemporalID = TID - 1)\r\n /*+---------------+---------------+\r\n *|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|\r\n *+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n *|F| Type | LayerId | TID |\r\n *+-------------+-----------------+\r\n */\r\n const packet = rtpPackets[i];\r\n\r\n const payload_header = (packet[0] << 8) | (packet[1]);\r\n const _payload_header_f_bit = (payload_header >> 15) & 0x01;\r\n const payload_header_type = (payload_header >> 9) & 0x3F;\r\n const _payload_header_layer_id = (payload_header >> 3) & 0x3F;\r\n const _payload_header_tid = payload_header & 0x7;\r\n\r\n // There are three ways to Packetize NAL units into RTP Packets\r\n // Single NAL Unit Packet\r\n // Aggregation Packet (payload_header_type = 48)\r\n // Fragmentation Unit (payload_header_type = 49)\r\n\r\n\r\n // Single NAL Unit Packet\r\n // 32=VPS\r\n // 33=SPS\r\n // 34=PPS\r\n if (payload_header_type != 48 && payload_header_type != 49) {\r\n //TODO - Handle DONL\r\n nals.push(packet);\r\n }\r\n\r\n // Aggregation Packet\r\n else if (payload_header_type == 48) {\r\n // TODO\r\n console.log(\"eek\");\r\n }\r\n\r\n\r\n // Fragmentation Unit\r\n else if (payload_header_type == 49) {\r\n //Console.WriteLine(\"Fragmentation Unit\");\r\n\r\n // 0 1 2 3 4 5 6 7\r\n // +-+-+-+-+-+-+-+-+\r\n // |S|E| FuType |\r\n // +---------------+\r\n //\r\n\r\n // Parse Fragmentation Unit Header\r\n const fu_header_s = (packet[2] >> 7) & 0x01; // start marker\r\n const fu_header_e = (packet[2] >> 6) & 0x01; // end marker\r\n const fu_header_type = (packet[2] >> 0) & 0x3F; // fu type\r\n\r\n // Console.WriteLine(\"Frag FU-A s=\" + fu_header_s + \"e=\" + fu_header_e);\r\n\r\n // Check Start and End flags\r\n if (fu_header_s == 1 && fu_header_e == 0) {\r\n // Start Fragment.\r\n // Initiise the partialNal byte array\r\n\r\n // Empty the partial NAL array\r\n partialNal = [];\r\n\r\n // Reconstrut the NAL header from the rtp_payload_header, replacing the Type with FU Type\r\n let nal_header = (payload_header & 0x81FF); // strip out existing 'type'\r\n nal_header = nal_header | (fu_header_type << 9);\r\n\r\n partialNal.push((nal_header >> 8) & 0xFF);\r\n partialNal.push((nal_header >> 0) & 0xFF);\r\n }\r\n\r\n\r\n // Copy the video data\r\n if (this.has_donl) {\r\n // start copying after the DONL data\r\n for (let x = 5; x < packet.length; x++) {\r\n partialNal.push(packet[x]); // not very efficient, copying one byte at a time\r\n }\r\n }\r\n else {\r\n // there is no DONL data\r\n for (let x = 3; x < packet.length; x++) {\r\n partialNal.push(packet[x]); // not very efficient, copying one byte at a time\r\n }\r\n }\r\n\r\n if (fu_header_s == 0 && fu_header_e == 1) {\r\n // End Fragment\r\n // Append this payload to the fragmented_nal\r\n\r\n // Add the NAL to the array of NAL units\r\n nals.push(Buffer.from(partialNal));\r\n }\r\n }\r\n else {\r\n //Console.WriteLine(\"Unknown Payload Header Type = \" + payload_header_type);\r\n }\r\n }\r\n\r\n // Write out all the NALs\r\n for (let x = 0; x < nals.length; x++) {\r\n this.stream.write(H265_HEADER);\r\n this.stream.write(nals[x]);\r\n }\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/transports/RTPPacket.d.ts b/dist/transports/RTPPacket.d.ts index 6644577..695a38a 100644 --- a/dist/transports/RTPPacket.d.ts +++ b/dist/transports/RTPPacket.d.ts @@ -1,6 +1,6 @@ /// declare class RTPPacket { - private _bufpkt; + private bufpkt; constructor(bufpayload: Buffer, hasHeader?: boolean); get type(): number; set type(val: number); diff --git a/dist/transports/RTPPacket.js b/dist/transports/RTPPacket.js index 87814a3..ee0d171 100644 --- a/dist/transports/RTPPacket.js +++ b/dist/transports/RTPPacket.js @@ -24,7 +24,7 @@ class RTPPacket { */ if (hasHeader && bufpayload.length >= 12) { // full packet (generally an incoming packet straight from the socket) - this._bufpkt = bufpayload; + this.bufpkt = bufpayload; /*V = (bufpkt[0] >>> 6 & 0x03); P = (bufpkt[0] >>> 5 & 0x01); X = (bufpkt[0] >>> 4 & 0x01); @@ -38,7 +38,7 @@ class RTPPacket { } else { // just payload data (for outgoing/sending) - this._bufpkt = buffer_1.Buffer.alloc(12 + bufpayload.length); // V..SSRC + payload + this.bufpkt = buffer_1.Buffer.alloc(12 + bufpayload.length); // V..SSRC + payload /*bufpkt[0] = (V << 6 | P << 5 | X << 4 | CC); bufpkt[1] = (M << 7 | PT); bufpkt[2] = (SN >>> 8) @@ -51,77 +51,77 @@ class RTPPacket { bufpkt[9] = (SSRC >>> 16 & 0xFF); bufpkt[10] = (SSRC >>> 8 & 0xFF); bufpkt[11] = (SSRC & 0xFF);*/ - this._bufpkt[0] = 0x80; - this._bufpkt[1] = 0; + this.bufpkt[0] = 0x80; + this.bufpkt[1] = 0; const SN = Math.floor(1000 * Math.random()); - this._bufpkt[2] = (SN >>> 8); - this._bufpkt[3] = (SN & 0xFF); - this._bufpkt[4] = 0; - this._bufpkt[5] = 0; - this._bufpkt[6] = 0; - this._bufpkt[7] = 1; - this._bufpkt[8] = 0; - this._bufpkt[9] = 0; - this._bufpkt[10] = 0; - this._bufpkt[11] = 1; - bufpayload.copy(this._bufpkt, 12, 0); // append payload data + this.bufpkt[2] = (SN >>> 8); + this.bufpkt[3] = (SN & 0xFF); + this.bufpkt[4] = 0; + this.bufpkt[5] = 0; + this.bufpkt[6] = 0; + this.bufpkt[7] = 1; + this.bufpkt[8] = 0; + this.bufpkt[9] = 0; + this.bufpkt[10] = 0; + this.bufpkt[11] = 1; + bufpayload.copy(this.bufpkt, 12, 0); // append payload data } } - get type() { return (this._bufpkt[1] & 0x7F); } + get type() { return (this.bufpkt[1] & 0x7F); } set type(val) { val = toUnsigned(val); if (val <= 127) { - this._bufpkt[1] -= (this._bufpkt[1] & 0x7F); - this._bufpkt[1] |= val; + this.bufpkt[1] -= (this.bufpkt[1] & 0x7F); + this.bufpkt[1] |= val; } } - get seq() { return (this._bufpkt[2] << 8 | this._bufpkt[3]); } + get seq() { return (this.bufpkt[2] << 8 | this.bufpkt[3]); } set seq(val) { val = toUnsigned(val); if (val <= 65535) { - this._bufpkt[2] = (val >>> 8); - this._bufpkt[3] = (val & 0xFF); + this.bufpkt[2] = (val >>> 8); + this.bufpkt[3] = (val & 0xFF); } } - get time() { return (this._bufpkt[4] << 24 | this._bufpkt[5] << 16 | this._bufpkt[6] << 8 | this._bufpkt[7]); } + get time() { return (this.bufpkt[4] << 24 | this.bufpkt[5] << 16 | this.bufpkt[6] << 8 | this.bufpkt[7]); } set time(val) { val = toUnsigned(val); if (val <= 4294967295) { - this._bufpkt[4] = (val >>> 24); - this._bufpkt[5] = (val >>> 16 & 0xFF); - this._bufpkt[6] = (val >>> 8 & 0xFF); - this._bufpkt[7] = (val & 0xFF); + this.bufpkt[4] = (val >>> 24); + this.bufpkt[5] = (val >>> 16 & 0xFF); + this.bufpkt[6] = (val >>> 8 & 0xFF); + this.bufpkt[7] = (val & 0xFF); } } - get source() { return (this._bufpkt[8] << 24 | this._bufpkt[9] << 16 | this._bufpkt[10] << 8 | this._bufpkt[11]); } + get source() { return (this.bufpkt[8] << 24 | this.bufpkt[9] << 16 | this.bufpkt[10] << 8 | this.bufpkt[11]); } set source(val) { val = toUnsigned(val); if (val <= 4294967295) { - this._bufpkt[8] = (val >>> 24); - this._bufpkt[9] = (val >>> 16 & 0xFF); - this._bufpkt[10] = (val >>> 8 & 0xFF); - this._bufpkt[11] = (val & 0xFF); + this.bufpkt[8] = (val >>> 24); + this.bufpkt[9] = (val >>> 16 & 0xFF); + this.bufpkt[10] = (val >>> 8 & 0xFF); + this.bufpkt[11] = (val & 0xFF); } } // Gets/Sets the payload of an existing RTP packet (without any RTP Headers) - get payload() { return (this._bufpkt.slice(12, this._bufpkt.length)); } + get payload() { return (this.bufpkt.slice(12, this.bufpkt.length)); } set payload(val) { if (buffer_1.Buffer.isBuffer(val)) { const newsize = 12 + val.length; - if (this._bufpkt.length == newsize) - val.copy(this._bufpkt, 12, 0); + if (this.bufpkt.length == newsize) + val.copy(this.bufpkt, 12, 0); else { const newbuf = buffer_1.Buffer.alloc(newsize); - this._bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header + this.bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header val.copy(newbuf, 12, 0); - this._bufpkt = newbuf; + this.bufpkt = newbuf; } } } // gets/sets the RTP Header and RTP Payload - get packet() { return this._bufpkt; } + get packet() { return this.bufpkt; } set packet(val) { - this._bufpkt = val; + this.bufpkt = val; } } exports.default = RTPPacket; diff --git a/dist/transports/RTPPacket.js.map b/dist/transports/RTPPacket.js.map index 3709fe5..1b7e13a 100644 --- a/dist/transports/RTPPacket.js.map +++ b/dist/transports/RTPPacket.js.map @@ -1 +1 @@ -{"version":3,"file":"RTPPacket.js","sourceRoot":"","sources":["../../lib/transports/RTPPacket.ts"],"names":[],"mappings":"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","sourcesContent":["// Packetize audio chunk to RTP packets \n// By Thangcq98, August 2022\n\nimport { Buffer } from \"buffer\";\n\nfunction toUnsigned(val: number): number {\n return ((val >>> 1) * 2 + (val & 1));\n}\n\nclass RTPPacket {\n private _bufpkt: Buffer; // holds the RTP header (12 bytes) AND the RTP packet payload\n\n constructor(bufpayload: Buffer, hasHeader = false) {\n /* See RFC3550 for more details: http://www.ietf.org/rfc/rfc3550.txt\n V = 2, // version. always 2 for this RFC (2 bits)\n P = 0, // padding. not supported yet, so always 0 (1 bit)\n X = 0, // header extension (1 bit)\n CC = 0, // CSRC count (4 bits)\n M = 0, // marker (1 bit)\n PT = 0, // payload type. see section 6 in RFC3551 for valid types: http://www.ietf.org/rfc/rfc3551.txt (7 bits)\n SN = Math.floor(1000 * Math.random()), // sequence number. SHOULD be random (16 bits)\n TS = 1, // timestamp in the format of NTP (# sec. since 0h UTC 1 January 1900)? (32 bits)\n SSRC = 1; // synchronization source (32 bits)\n //CSRC = 0, // contributing sources. not supported yet (32 bits)\n //DP = 0, // header extension, 'Defined By Profile'. not supported yet (16 bits)\n //EL = 0; // header extension length. not supported yet (16 bits)\n */\n if (hasHeader && bufpayload.length >= 12) {\n // full packet (generally an incoming packet straight from the socket)\n this._bufpkt = bufpayload;\n /*V = (bufpkt[0] >>> 6 & 0x03);\n P = (bufpkt[0] >>> 5 & 0x01);\n X = (bufpkt[0] >>> 4 & 0x01);\n CC = (bufpkt[0] & 0x0F);\n M = (bufpkt[1] >>> 7 & 0x01);\n PT = (bufpkt[1] & 0x7F);\n SN = (bufpkt[2] << 8 | bufpkt[3]);\n TS = (bufpkt[4] << 24 | bufpkt[5] << 16 | bufpkt[6] << 8 | bufpkt[7]);\n SSRC = (bufpkt[8] << 24 | bufpkt[9] << 16 | bufpkt[10] << 8 | bufpkt[11]);*/\n // bufpkt[12..bufpkg.length-1] == payload data\n } else {\n // just payload data (for outgoing/sending)\n this._bufpkt = new Buffer(12 + bufpayload.length); // V..SSRC + payload\n /*bufpkt[0] = (V << 6 | P << 5 | X << 4 | CC);\n bufpkt[1] = (M << 7 | PT);\n bufpkt[2] = (SN >>> 8)\n bufpkt[3] = (SN & 0xFF);\n bufpkt[4] = (TS >>> 24);\n bufpkt[5] = (TS >>> 16 & 0xFF);\n bufpkt[6] = (TS >>> 8 & 0xFF);\n bufpkt[7] = (TS & 0xFF);\n bufpkt[8] = (SSRC >>> 24);\n bufpkt[9] = (SSRC >>> 16 & 0xFF);\n bufpkt[10] = (SSRC >>> 8 & 0xFF);\n bufpkt[11] = (SSRC & 0xFF);*/\n this._bufpkt[0] = 0x80;\n this._bufpkt[1] = 0;\n const SN = Math.floor(1000 * Math.random());\n this._bufpkt[2] = (SN >>> 8)\n this._bufpkt[3] = (SN & 0xFF);\n this._bufpkt[4] = 0;\n this._bufpkt[5] = 0;\n this._bufpkt[6] = 0;\n this._bufpkt[7] = 1;\n this._bufpkt[8] = 0;\n this._bufpkt[9] = 0;\n this._bufpkt[10] = 0;\n this._bufpkt[11] = 1;\n bufpayload.copy(this._bufpkt, 12, 0); // append payload data\n }\n }\n\n public get type() { return (this._bufpkt[1] & 0x7F); }\n public set type(val) {\n val = toUnsigned(val);\n if (val <= 127) {\n this._bufpkt[1] -= (this._bufpkt[1] & 0x7F);\n this._bufpkt[1] |= val;\n }\n }\n\n public get seq() { return (this._bufpkt[2] << 8 | this._bufpkt[3]); }\n public set seq(val) {\n val = toUnsigned(val);\n if (val <= 65535) {\n this._bufpkt[2] = (val >>> 8);\n this._bufpkt[3] = (val & 0xFF);\n }\n }\n\n public get time() { return (this._bufpkt[4] << 24 | this._bufpkt[5] << 16 | this._bufpkt[6] << 8 | this._bufpkt[7]); }\n public set time(val) {\n val = toUnsigned(val);\n if (val <= 4294967295) {\n this._bufpkt[4] = (val >>> 24);\n this._bufpkt[5] = (val >>> 16 & 0xFF);\n this._bufpkt[6] = (val >>> 8 & 0xFF);\n this._bufpkt[7] = (val & 0xFF);\n }\n }\n\n public get source() { return (this._bufpkt[8] << 24 | this._bufpkt[9] << 16 | this._bufpkt[10] << 8 | this._bufpkt[11]); }\n public set source(val) {\n val = toUnsigned(val);\n if (val <= 4294967295) {\n this._bufpkt[8] = (val >>> 24);\n this._bufpkt[9] = (val >>> 16 & 0xFF);\n this._bufpkt[10] = (val >>> 8 & 0xFF);\n this._bufpkt[11] = (val & 0xFF);\n }\n }\n\n // Gets/Sets the payload of an existing RTP packet (without any RTP Headers)\n public get payload() { return (this._bufpkt.slice(12, this._bufpkt.length)); }\n public set payload(val) {\n if (Buffer.isBuffer(val)) {\n const newsize = 12 + val.length;\n if (this._bufpkt.length == newsize)\n val.copy(this._bufpkt, 12, 0);\n else {\n const newbuf = new Buffer(newsize);\n this._bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header\n val.copy(newbuf, 12, 0);\n this._bufpkt = newbuf;\n }\n }\n }\n\n // gets/sets the RTP Header and RTP Payload\n public get packet() { return this._bufpkt; }\n public set packet(val) {\n this._bufpkt = val;\n }\n}\n\nexport default RTPPacket;"]} +{"version":3,"file":"RTPPacket.js","sourceRoot":"","sources":["../../lib/transports/RTPPacket.ts"],"names":[],"mappings":"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","sourcesContent":["// Packetize audio chunk to RTP packets \r\n// By Thangcq98, August 2022\r\n\r\nimport { Buffer } from \"buffer\";\r\n\r\nfunction toUnsigned(val: number): number {\r\n return ((val >>> 1) * 2 + (val & 1));\r\n}\r\n\r\nclass RTPPacket {\r\n private bufpkt: Buffer; // holds the RTP header (12 bytes) AND the RTP packet payload\r\n\r\n constructor(bufpayload: Buffer, hasHeader = false) {\r\n /* See RFC3550 for more details: http://www.ietf.org/rfc/rfc3550.txt\r\n V = 2, // version. always 2 for this RFC (2 bits)\r\n P = 0, // padding. not supported yet, so always 0 (1 bit)\r\n X = 0, // header extension (1 bit)\r\n CC = 0, // CSRC count (4 bits)\r\n M = 0, // marker (1 bit)\r\n PT = 0, // payload type. see section 6 in RFC3551 for valid types: http://www.ietf.org/rfc/rfc3551.txt (7 bits)\r\n SN = Math.floor(1000 * Math.random()), // sequence number. SHOULD be random (16 bits)\r\n TS = 1, // timestamp in the format of NTP (# sec. since 0h UTC 1 January 1900)? (32 bits)\r\n SSRC = 1; // synchronization source (32 bits)\r\n //CSRC = 0, // contributing sources. not supported yet (32 bits)\r\n //DP = 0, // header extension, 'Defined By Profile'. not supported yet (16 bits)\r\n //EL = 0; // header extension length. not supported yet (16 bits)\r\n */\r\n if (hasHeader && bufpayload.length >= 12) {\r\n // full packet (generally an incoming packet straight from the socket)\r\n this.bufpkt = bufpayload;\r\n /*V = (bufpkt[0] >>> 6 & 0x03);\r\n P = (bufpkt[0] >>> 5 & 0x01);\r\n X = (bufpkt[0] >>> 4 & 0x01);\r\n CC = (bufpkt[0] & 0x0F);\r\n M = (bufpkt[1] >>> 7 & 0x01);\r\n PT = (bufpkt[1] & 0x7F);\r\n SN = (bufpkt[2] << 8 | bufpkt[3]);\r\n TS = (bufpkt[4] << 24 | bufpkt[5] << 16 | bufpkt[6] << 8 | bufpkt[7]);\r\n SSRC = (bufpkt[8] << 24 | bufpkt[9] << 16 | bufpkt[10] << 8 | bufpkt[11]);*/\r\n // bufpkt[12..bufpkg.length-1] == payload data\r\n } else {\r\n // just payload data (for outgoing/sending)\r\n this.bufpkt = Buffer.alloc(12 + bufpayload.length); // V..SSRC + payload\r\n /*bufpkt[0] = (V << 6 | P << 5 | X << 4 | CC);\r\n bufpkt[1] = (M << 7 | PT);\r\n bufpkt[2] = (SN >>> 8)\r\n bufpkt[3] = (SN & 0xFF);\r\n bufpkt[4] = (TS >>> 24);\r\n bufpkt[5] = (TS >>> 16 & 0xFF);\r\n bufpkt[6] = (TS >>> 8 & 0xFF);\r\n bufpkt[7] = (TS & 0xFF);\r\n bufpkt[8] = (SSRC >>> 24);\r\n bufpkt[9] = (SSRC >>> 16 & 0xFF);\r\n bufpkt[10] = (SSRC >>> 8 & 0xFF);\r\n bufpkt[11] = (SSRC & 0xFF);*/\r\n this.bufpkt[0] = 0x80;\r\n this.bufpkt[1] = 0;\r\n const SN = Math.floor(1000 * Math.random());\r\n this.bufpkt[2] = (SN >>> 8)\r\n this.bufpkt[3] = (SN & 0xFF);\r\n this.bufpkt[4] = 0;\r\n this.bufpkt[5] = 0;\r\n this.bufpkt[6] = 0;\r\n this.bufpkt[7] = 1;\r\n this.bufpkt[8] = 0;\r\n this.bufpkt[9] = 0;\r\n this.bufpkt[10] = 0;\r\n this.bufpkt[11] = 1;\r\n bufpayload.copy(this.bufpkt, 12, 0); // append payload data\r\n }\r\n }\r\n\r\n public get type() { return (this.bufpkt[1] & 0x7F); }\r\n public set type(val) {\r\n val = toUnsigned(val);\r\n if (val <= 127) {\r\n this.bufpkt[1] -= (this.bufpkt[1] & 0x7F);\r\n this.bufpkt[1] |= val;\r\n }\r\n }\r\n\r\n public get seq() { return (this.bufpkt[2] << 8 | this.bufpkt[3]); }\r\n public set seq(val) {\r\n val = toUnsigned(val);\r\n if (val <= 65535) {\r\n this.bufpkt[2] = (val >>> 8);\r\n this.bufpkt[3] = (val & 0xFF);\r\n }\r\n }\r\n\r\n public get time() { return (this.bufpkt[4] << 24 | this.bufpkt[5] << 16 | this.bufpkt[6] << 8 | this.bufpkt[7]); }\r\n public set time(val) {\r\n val = toUnsigned(val);\r\n if (val <= 4294967295) {\r\n this.bufpkt[4] = (val >>> 24);\r\n this.bufpkt[5] = (val >>> 16 & 0xFF);\r\n this.bufpkt[6] = (val >>> 8 & 0xFF);\r\n this.bufpkt[7] = (val & 0xFF);\r\n }\r\n }\r\n\r\n public get source() { return (this.bufpkt[8] << 24 | this.bufpkt[9] << 16 | this.bufpkt[10] << 8 | this.bufpkt[11]); }\r\n public set source(val) {\r\n val = toUnsigned(val);\r\n if (val <= 4294967295) {\r\n this.bufpkt[8] = (val >>> 24);\r\n this.bufpkt[9] = (val >>> 16 & 0xFF);\r\n this.bufpkt[10] = (val >>> 8 & 0xFF);\r\n this.bufpkt[11] = (val & 0xFF);\r\n }\r\n }\r\n\r\n // Gets/Sets the payload of an existing RTP packet (without any RTP Headers)\r\n public get payload() { return (this.bufpkt.slice(12, this.bufpkt.length)); }\r\n public set payload(val) {\r\n if (Buffer.isBuffer(val)) {\r\n const newsize = 12 + val.length;\r\n if (this.bufpkt.length == newsize)\r\n val.copy(this.bufpkt, 12, 0);\r\n else {\r\n const newbuf = Buffer.alloc(newsize);\r\n this.bufpkt.copy(newbuf, 0, 0, 12); // copy the RTP header\r\n val.copy(newbuf, 12, 0);\r\n this.bufpkt = newbuf;\r\n }\r\n }\r\n }\r\n\r\n // gets/sets the RTP Header and RTP Payload\r\n public get packet() { return this.bufpkt; }\r\n public set packet(val) {\r\n this.bufpkt = val;\r\n }\r\n}\r\n\r\nexport default RTPPacket;"]} \ No newline at end of file diff --git a/dist/util.js b/dist/util.js index 8d13d0e..7062a73 100644 --- a/dist/util.js +++ b/dist/util.js @@ -44,7 +44,7 @@ function parseRTCPPacket(buffer) { const packetType = buffer[1]; const length = buffer[2] << 8 + buffer[3]; // The length in 32 bit words (not the length in bytes) const ssrc = buffer[4] << 24 + buffer[5] << 16 + buffer[6] << 8 + buffer[7]; - let result = { + const result = { buffer, version, padding, @@ -54,7 +54,7 @@ function parseRTCPPacket(buffer) { packetType }; if (packetType == 200) { - let senderReport = { + const senderReport = { ntpTimestampMSW: buffer.readUInt32BE(8), ntpTimestampLSW: buffer.readUInt32BE(12), rtpTimestamp: buffer.readUInt32BE(16), diff --git a/dist/util.js.map b/dist/util.js.map index 43e3af6..e1a57be 100644 --- a/dist/util.js.map +++ b/dist/util.js.map @@ -1 +1 @@ -{"version":3,"file":"util.js","sourceRoot":"","sources":["../lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\r\n\r\nexport interface RTPPacket {\r\n id: number;\r\n timestamp: number;\r\n marker: number;\r\n padding: number;\r\n hasExtensions: number;\r\n\r\n payload: Buffer;\r\n\r\n length: number;\r\n paddingLength: number;\r\n\r\n payloadType: number;\r\n\r\n // Additional information added to the Packet\r\n wallclockTime?: Date;\r\n}\r\n\r\nexport function parseRTPPacket(buffer: Buffer): RTPPacket {\r\n const padding = (buffer[0] >> 5) & 0x01\r\n let paddingLength = 0;\r\n if (padding == 1) {\r\n // padding size is the last byte of the RTP data\r\n paddingLength = buffer[buffer.length - 1];\r\n }\r\n const hasExtensions = (buffer[0] >> 4) & 0x01;\r\n const marker = (buffer[1]) >>> 7;\r\n const payloadType = buffer[1] & 0x7f;\r\n const num_csrc_identifiers = (buffer[0] & 0x0F);\r\n\r\n const payload = buffer.slice((num_csrc_identifiers * 4) + (hasExtensions ? 16 : 12)); // includes padding\r\n const length = payload.length;\r\n\r\n\r\n return {\r\n id: buffer.readUInt16BE(2),\r\n timestamp: buffer.readUInt32BE(4),\r\n marker,\r\n padding,\r\n payloadType,\r\n hasExtensions,\r\n payload,\r\n length,\r\n paddingLength,\r\n };\r\n}\r\n\r\nexport interface SenderReport {\r\n ntpTimestampMSW: number;\r\n ntpTimestampLSW: number;\r\n rtpTimestamp: number;\r\n senderPacketCount: number;\r\n senderOctetCount: number;\r\n}\r\n\r\nexport interface RTCPPacket {\r\n buffer: Buffer;\r\n version: number;\r\n padding: number;\r\n receptionReportCount: number;\r\n packetType: number;\r\n length: number;\r\n ssrc: number;\r\n\r\n senderReport?: SenderReport;\r\n}\r\n\r\nexport function parseRTCPPacket(buffer: Buffer): RTCPPacket {\r\n\r\n // Packet Types\r\n // SR Sender Report 200\r\n // RR Receiver Report 201\r\n // SDES Source Description 202\r\n // BYE Goodbye 203\r\n // APP Application-Defined 204\r\n // RTPFB Generic RTP feedback 205\r\n // PSFB Payload-specific feedback 206\r\n // XR RTCP Extension 207\r\n const version = (buffer[0] >> 6);\r\n const padding = (buffer[0] >> 5) & 0x01;\r\n const receptionReportCount = (buffer[0]) & 0x1F;\r\n const packetType = buffer[1];\r\n const length = buffer[2] << 8 + buffer[3]; // The length in 32 bit words (not the length in bytes)\r\n const ssrc = buffer[4] << 24 + buffer[5] << 16 + buffer[6] << 8 + buffer[7];\r\n\r\n let result: RTCPPacket = {\r\n buffer,\r\n version,\r\n padding,\r\n length,\r\n ssrc,\r\n receptionReportCount,\r\n packetType};\r\n\r\n if (packetType == 200) {\r\n let senderReport: SenderReport = {\r\n ntpTimestampMSW: buffer.readUInt32BE(8),\r\n ntpTimestampLSW: buffer.readUInt32BE(12),\r\n rtpTimestamp: buffer.readUInt32BE(16),\r\n senderPacketCount: buffer.readUInt32BE(20),\r\n senderOctetCount: buffer.readUInt32BE(24)\r\n };\r\n\r\n result.senderReport = senderReport;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n// utility function for using crypto library\r\nexport function getMD5Hash(str: string): string {\r\n const md5 = createHash(\"md5\");\r\n md5.update(str);\r\n\r\n return md5.digest(\"hex\");\r\n}\r\n\r\nexport function getSHA256Hash(str: string): string {\r\n const sha256 = createHash(\"sha256\"); // use getHashes() to see what is supported\r\n sha256.update(str);\r\n\r\n return sha256.digest(\"hex\");\r\n}\r\n\r\nexport interface Transport {\r\n protocol: string;\r\n parameters: { [key: string]: string };\r\n}\r\n\r\nexport function parseTransport(transport: string): Transport {\r\n const parameters: { [key: string]: string } = {};\r\n\r\n const parts = transport.split(\";\");\r\n const protocol = parts[0];\r\n\r\n for (let i = 0; i < parts.length; i++) {\r\n const part = parts[i];\r\n const index = part.indexOf(\"=\");\r\n\r\n if (index > -1 && index !== part.length - 1) {\r\n parameters[part.substring(0, index)] = part.substring(index + 1);\r\n }\r\n }\r\n\r\n return {\r\n protocol,\r\n parameters\r\n };\r\n}\r\n\r\nexport function randInclusive(min: number, max: number): number {\r\n min = Math.ceil(min);\r\n max = Math.floor(max);\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n}\r\n\r\nexport function generateSSRC(): number {\r\n return randInclusive(1, 0xffffffff);\r\n}\r\n\r\n// BitStream classes by 2018 Roger Hardiman, RJH Technical Consultancy Ltd\r\n// Write to a bitstream and read back as an array\r\n\r\nexport class BitStream {\r\n\r\n data: number[] = []; // Array only stores 0 or 1 (one 'bit' per buffer item)\r\n // not very efficient on memory\r\n\r\n // Constructor\r\n // constructor() {}\r\n \r\n // Functions\r\n AddValue(value: number, num_bits: number): void {\r\n // Add each bit to the List\r\n for (let i = num_bits - 1; i >= 0; i--) {\r\n this.data.push((value >> i) & 0x01);\r\n }\r\n }\r\n\r\n AddHexString(hex_string: string): void {\r\n const hex_chars = hex_string.toUpperCase();\r\n\r\n for (let x = 0; x < hex_chars.length; x++) {\r\n const c = hex_chars.charAt(x);\r\n if (c == '0') this.AddValue(0, 4);\r\n else if (c == '1') this.AddValue(1, 4);\r\n else if (c == '2') this.AddValue(2, 4);\r\n else if (c == '3') this.AddValue(3, 4);\r\n else if (c == '4') this.AddValue(4, 4);\r\n else if (c == '5') this.AddValue(5, 4);\r\n else if (c == '6') this.AddValue(6, 4);\r\n else if (c == '7') this.AddValue(7, 4);\r\n else if (c == '8') this.AddValue(8, 4);\r\n else if (c == '9') this.AddValue(9, 4);\r\n else if (c == 'A') this.AddValue(10, 4);\r\n else if (c == 'B') this.AddValue(11, 4);\r\n else if (c == 'C') this.AddValue(12, 4);\r\n else if (c == 'D') this.AddValue(13, 4);\r\n else if (c == 'E') this.AddValue(14, 4);\r\n else if (c == 'F') this.AddValue(15, 4);\r\n }\r\n }\r\n\r\n Read(num_bits: number): number {\r\n // Read and remove items from the front of the list of bits\r\n if (this.data.length < num_bits) return 0;\r\n let result = 0;\r\n for (let i = 0; i < num_bits; i++) {\r\n result = result << 1;\r\n result = result + this.data[0];\r\n this.data.shift(); // remove the first item from the array\r\n }\r\n return result;\r\n }\r\n\r\n ToArray(): Buffer {\r\n const num_bytes = Math.ceil(this.data.length / 8.0);\r\n const array = Buffer.alloc(num_bytes);\r\n let ptr = 0;\r\n let shift = 7;\r\n for (let i = 0; i < this.data.length; i++) {\r\n array[ptr] += (this.data[i] << shift);\r\n if (shift == 0) {\r\n shift = 7;\r\n ptr++;\r\n }\r\n else {\r\n shift--;\r\n }\r\n }\r\n\r\n return array;\r\n }\r\n}\r\n"]} \ No newline at end of file +{"version":3,"file":"util.js","sourceRoot":"","sources":["../lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\n\nexport interface RTPPacket {\n id: number;\n timestamp: number;\n marker: number;\n padding: number;\n hasExtensions: number;\n\n payload: Buffer;\n\n length: number;\n paddingLength: number;\n\n payloadType: number;\n\n // Additional information added to the Packet\n wallclockTime?: Date;\n}\n\nexport function parseRTPPacket(buffer: Buffer): RTPPacket {\n const padding = (buffer[0] >> 5) & 0x01\n let paddingLength = 0;\n if (padding == 1) {\n // padding size is the last byte of the RTP data\n paddingLength = buffer[buffer.length - 1];\n }\n const hasExtensions = (buffer[0] >> 4) & 0x01;\n const marker = (buffer[1]) >>> 7;\n const payloadType = buffer[1] & 0x7f;\n const num_csrc_identifiers = (buffer[0] & 0x0F);\n\n const payload = buffer.slice((num_csrc_identifiers * 4) + (hasExtensions ? 16 : 12)); // includes padding\n const length = payload.length;\n\n\n return {\n id: buffer.readUInt16BE(2),\n timestamp: buffer.readUInt32BE(4),\n marker,\n padding,\n payloadType,\n hasExtensions,\n payload,\n length,\n paddingLength,\n };\n}\n\nexport interface SenderReport {\n ntpTimestampMSW: number;\n ntpTimestampLSW: number;\n rtpTimestamp: number;\n senderPacketCount: number;\n senderOctetCount: number;\n}\n\nexport interface RTCPPacket {\n buffer: Buffer;\n version: number;\n padding: number;\n receptionReportCount: number;\n packetType: number;\n length: number;\n ssrc: number;\n\n senderReport?: SenderReport;\n}\n\nexport function parseRTCPPacket(buffer: Buffer): RTCPPacket {\n\n // Packet Types\n // SR Sender Report 200\n // RR Receiver Report 201\n // SDES Source Description 202\n // BYE Goodbye 203\n // APP Application-Defined 204\n // RTPFB Generic RTP feedback 205\n // PSFB Payload-specific feedback 206\n // XR RTCP Extension 207\n const version = (buffer[0] >> 6);\n const padding = (buffer[0] >> 5) & 0x01;\n const receptionReportCount = (buffer[0]) & 0x1F;\n const packetType = buffer[1];\n const length = buffer[2] << 8 + buffer[3]; // The length in 32 bit words (not the length in bytes)\n const ssrc = buffer[4] << 24 + buffer[5] << 16 + buffer[6] << 8 + buffer[7];\n\n const result: RTCPPacket = {\n buffer,\n version,\n padding,\n length,\n ssrc,\n receptionReportCount,\n packetType};\n\n if (packetType == 200) {\n const senderReport: SenderReport = {\n ntpTimestampMSW: buffer.readUInt32BE(8),\n ntpTimestampLSW: buffer.readUInt32BE(12),\n rtpTimestamp: buffer.readUInt32BE(16),\n senderPacketCount: buffer.readUInt32BE(20),\n senderOctetCount: buffer.readUInt32BE(24)\n };\n\n result.senderReport = senderReport;\n }\n\n return result;\n}\n\n// utility function for using crypto library\nexport function getMD5Hash(str: string): string {\n const md5 = createHash(\"md5\");\n md5.update(str);\n\n return md5.digest(\"hex\");\n}\n\nexport function getSHA256Hash(str: string): string {\n const sha256 = createHash(\"sha256\"); // use getHashes() to see what is supported\n sha256.update(str);\n\n return sha256.digest(\"hex\");\n}\n\nexport interface Transport {\n protocol: string;\n parameters: { [key: string]: string };\n}\n\nexport function parseTransport(transport: string): Transport {\n const parameters: { [key: string]: string } = {};\n\n const parts = transport.split(\";\");\n const protocol = parts[0];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const index = part.indexOf(\"=\");\n\n if (index > -1 && index !== part.length - 1) {\n parameters[part.substring(0, index)] = part.substring(index + 1);\n }\n }\n\n return {\n protocol,\n parameters\n };\n}\n\nexport function randInclusive(min: number, max: number): number {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nexport function generateSSRC(): number {\n return randInclusive(1, 0xffffffff);\n}\n\n// BitStream classes by 2018 Roger Hardiman, RJH Technical Consultancy Ltd\n// Write to a bitstream and read back as an array\n\nexport class BitStream {\n\n data: number[] = []; // Array only stores 0 or 1 (one 'bit' per buffer item)\n // not very efficient on memory\n\n // Constructor\n // constructor() {}\n \n // Functions\n AddValue(value: number, num_bits: number): void {\n // Add each bit to the List\n for (let i = num_bits - 1; i >= 0; i--) {\n this.data.push((value >> i) & 0x01);\n }\n }\n\n AddHexString(hex_string: string): void {\n const hex_chars = hex_string.toUpperCase();\n\n for (let x = 0; x < hex_chars.length; x++) {\n const c = hex_chars.charAt(x);\n if (c == '0') this.AddValue(0, 4);\n else if (c == '1') this.AddValue(1, 4);\n else if (c == '2') this.AddValue(2, 4);\n else if (c == '3') this.AddValue(3, 4);\n else if (c == '4') this.AddValue(4, 4);\n else if (c == '5') this.AddValue(5, 4);\n else if (c == '6') this.AddValue(6, 4);\n else if (c == '7') this.AddValue(7, 4);\n else if (c == '8') this.AddValue(8, 4);\n else if (c == '9') this.AddValue(9, 4);\n else if (c == 'A') this.AddValue(10, 4);\n else if (c == 'B') this.AddValue(11, 4);\n else if (c == 'C') this.AddValue(12, 4);\n else if (c == 'D') this.AddValue(13, 4);\n else if (c == 'E') this.AddValue(14, 4);\n else if (c == 'F') this.AddValue(15, 4);\n }\n }\n\n Read(num_bits: number): number {\n // Read and remove items from the front of the list of bits\n if (this.data.length < num_bits) return 0;\n let result = 0;\n for (let i = 0; i < num_bits; i++) {\n result = result << 1;\n result = result + this.data[0];\n this.data.shift(); // remove the first item from the array\n }\n return result;\n }\n\n ToArray(): Buffer {\n const num_bytes = Math.ceil(this.data.length / 8.0);\n const array = Buffer.alloc(num_bytes);\n let ptr = 0;\n let shift = 7;\n for (let i = 0; i < this.data.length; i++) {\n array[ptr] += (this.data[i] << shift);\n if (shift == 0) {\n shift = 7;\n ptr++;\n }\n else {\n shift--;\n }\n }\n\n return array;\n }\n}\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 19c1df2..ea93225 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,9 @@ "typedoc": "^0.23.25", "typedoc-plugin-markdown": "^3.14.0", "typescript": "^4.9.5" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@ampproject/remapping": {