diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f9185791af15e1cbf15957a9ce09b39fabd5d80..de4471308b301f3f1b7595ae07e04c781d73b71e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,8 @@ ## Install +If you're developing under MSWindows. You need to work from WSL. + [nodeJS](https://nodejs.org/en/download) ## Launch the app diff --git a/README.md b/README.md index f124c07fcd39a30ed09f5b8f6dedab7af7f0cc33..b90934458f2bc68101992279887727cdc54a7082 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,6 @@ Using: - docker for packaging Libraries: -- fastboot.js (License: MIT): https://github.com/kdrag0n/fastboot.js/ +- fastboot.js (License: MIT): https://gitlab.e.foundation/e/tools/fastboot.js - ya-webadb (License: MIT): https://github.com/yume-chan/ya-webadb - and more see [package.json](https://gitlab.e.foundation/e/devices/eos-installer/-/blob/main/app/package.json) diff --git a/app/.npmrc b/app/.npmrc new file mode 100644 index 0000000000000000000000000000000000000000..d9ecbb4090f1e20f739c165dd29a946ad4472f28 --- /dev/null +++ b/app/.npmrc @@ -0,0 +1 @@ +@e:registry=https://gitlab.e.foundation/api/v4/packages/npm/ diff --git a/app/package-lock.json b/app/package-lock.json index 1639b4ac2bf22be5a816213cf2bbc2d9d215c6f2..cfee925cb87fa682cb5d25b58d1715e7cf7ab100 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.9", "license": "GPLv3", "dependencies": { + "@e/fastboot": "1.1.4", "@zip.js/zip.js": "^2.7.54", "ky": "^1.7.4" }, @@ -17,7 +18,17 @@ "eslint": "^9.17.0", "globals": "^15.14.0", "prettier": "3.4.2", - "vite": "^6.0.5" + "vite": "^6.0.5", + "vite-plugin-static-copy": "^2.2.0" + } + }, + "node_modules/@e/fastboot": { + "version": "1.1.4", + "resolved": "https://gitlab.e.foundation/api/v4/projects/1751/packages/npm/@e/fastboot/-/@e/fastboot-1.1.4.tgz", + "integrity": "sha1-aJPGtwFhrnnf0ktIJH47kVvlV+k=", + "dependencies": { + "@zip.js/zip.js": "^2.7.6", + "pako": "^2.1.0" } }, "node_modules/@esbuild/linux-x64": { @@ -243,6 +254,44 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.29.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", @@ -352,6 +401,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -366,6 +429,19 @@ "dev": true, "license": "MIT" }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -377,6 +453,19 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -404,6 +493,44 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -686,6 +813,36 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -700,6 +857,16 @@ "dev": true, "license": "MIT" }, + "node_modules/fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -713,6 +880,19 @@ "node": ">=16.0.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -751,6 +931,36 @@ "dev": true, "license": "ISC" }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -777,6 +987,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -824,6 +1041,19 @@ "node": ">=0.8.19" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -847,6 +1077,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -888,6 +1128,19 @@ "dev": true, "license": "MIT" }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -947,6 +1200,30 @@ "dev": true, "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -993,6 +1270,16 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -1043,6 +1330,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1083,6 +1376,19 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", @@ -1148,6 +1454,40 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1158,6 +1498,17 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.29.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", @@ -1197,6 +1548,30 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1256,6 +1631,19 @@ "node": ">=8" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1269,6 +1657,16 @@ "node": ">= 0.8.0" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1351,6 +1749,25 @@ } } }, + "node_modules/vite-plugin-static-copy": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz", + "integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.3", + "fast-glob": "^3.2.11", + "fs-extra": "^11.1.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/app/package.json b/app/package.json index 48272bcb25f29346792142f74764b7eb1fcedb91..ecfc3cb86da5cceb8fa2ee89dead854ad7b7e34b 100644 --- a/app/package.json +++ b/app/package.json @@ -15,9 +15,11 @@ "eslint": "^9.17.0", "globals": "^15.14.0", "prettier": "3.4.2", - "vite": "^6.0.5" + "vite": "^6.0.5", + "vite-plugin-static-copy": "^2.2.0" }, "dependencies": { + "@e/fastboot": "1.1.4", "@zip.js/zip.js": "^2.7.54", "ky": "^1.7.4" } diff --git a/app/src/controller/device/bootloader.class.js b/app/src/controller/device/bootloader.class.js index 86df50c2869f37e59b3d0a77524cca7734605807..5c34fd353e107b5df4a779ba927a70097aeb9890 100644 --- a/app/src/controller/device/bootloader.class.js +++ b/app/src/controller/device/bootloader.class.js @@ -1,5 +1,10 @@ -import * as fastboot from "../../lib/fastboot/fastboot.js"; -import { TimeoutError } from "../../lib/fastboot/fastboot.js"; +import { + configureZip, + FastbootDevice, + setDebugLevel, + TimeoutError, + USER_ACTION_MAP, +} from "@e/fastboot"; import { Device } from "./device.class.js"; import { WDebug } from "../../debug.js"; @@ -8,18 +13,18 @@ import { WDebug } from "../../debug.js"; * */ export class Bootloader extends Device { constructor() { - super(new fastboot.FastbootDevice()); + super(new FastbootDevice()); } async init() { //await this.blobStore.init(); - fastboot.configureZip({ + configureZip({ workerScripts: { - inflate: ["../dist/vendor/z-worker-pako.js", "pako_inflate.min.js"], + inflate: ["/vendor/z-worker-pako.js", "pako_inflate.min.js"], }, }); // Enable verbose debug logging - fastboot.setDebugLevel(2); + setDebugLevel(2); } reboot(mode) { @@ -61,7 +66,7 @@ export class Bootloader extends Device { onReconnect, // Progress callback (action, item, progress) => { - let userAction = fastboot.USER_ACTION_MAP[action]; + let userAction = USER_ACTION_MAP[action]; onProgress(userAction, item, progress); }, ); diff --git a/app/src/lib/fastboot/fastboot.js b/app/src/lib/fastboot/fastboot.js deleted file mode 100644 index cfdd1dc1015757b87f07de44a8db22a1ee02cd61..0000000000000000000000000000000000000000 --- a/app/src/lib/fastboot/fastboot.js +++ /dev/null @@ -1,9754 +0,0 @@ -const ZIP_ENTRY_HEADER_BEGIN_LENGTH = 30; // bytes -var DebugLevel; -(function (DebugLevel) { - DebugLevel[DebugLevel["Silent"] = 0] = "Silent"; - DebugLevel[DebugLevel["Debug"] = 1] = "Debug"; - DebugLevel[DebugLevel["Verbose"] = 2] = "Verbose"; -})(DebugLevel || (DebugLevel = {})); -let debugLevel = DebugLevel.Silent; -function logDebug(...data) { - if (debugLevel >= 1) { - console.log(...data); - } -} -function logVerbose(...data) { - if (debugLevel >= 2) { - console.log(...data); - } -} -/** - * Change the debug level for the fastboot client: - * - 0 = silent - * - 1 = debug, recommended for general use - * - 2 = verbose, for debugging only - * - * @param {number} level - Debug level to use. - */ -function setDebugLevel(level) { - debugLevel = level; -} -/** - * Reads all of the data in the given blob and returns it as an ArrayBuffer. - * - * @param {Blob} blob - Blob with the data to read. - * @returns {Promise} ArrayBuffer containing data from the blob. - * @ignore - */ -function readBlobAsBuffer(blob) { - return new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.onload = () => { - resolve(reader.result); - }; - reader.onerror = () => { - reject(reader.error); - }; - reader.readAsArrayBuffer(blob); - }); -} -function waitForFrame() { - return new Promise((resolve, _reject) => { - window.requestAnimationFrame(resolve); - }); -} -async function runWithTimedProgress(onProgress, action, item, duration, workPromise) { - let startTime = new Date().getTime(); - let stop = false; - onProgress(action, item, 0.0); - let progressPromise = (async () => { - let now; - let targetTime = startTime + duration; - do { - now = new Date().getTime(); - onProgress(action, item, (now - startTime) / duration); - await waitForFrame(); - } while (!stop && now < targetTime); - })(); - await Promise.race([progressPromise, workPromise]); - stop = true; - await progressPromise; - await workPromise; - onProgress(action, item, 1.0); -} -/** Exception class for operations that exceeded their timeout duration. */ -class TimeoutError extends Error { - constructor(timeout) { - super(`Timeout of ${timeout} ms exceeded`); - this.name = "TimeoutError"; - this.timeout = timeout; - } -} -function runWithTimeout(promise, timeout) { - return new Promise((resolve, reject) => { - // Set up timeout - let timedOut = false; - let tid = setTimeout(() => { - // Set sentinel first to prevent race in promise resolving - timedOut = true; - reject(new TimeoutError(timeout)); - }, timeout); - // Passthrough - promise - .then((val) => { - if (!timedOut) { - resolve(val); - } - }) - .catch((err) => { - if (!timedOut) { - reject(err); - } - }) - .finally(() => { - if (!timedOut) { - clearTimeout(tid); - } - }); - }); -} -async function getEntryMetadata(blob, entry) { - const offset = entry.offset; - const headerBeginRaw = await blob.slice(offset, offset + ZIP_ENTRY_HEADER_BEGIN_LENGTH).arrayBuffer(); - const dataView = new DataView(headerBeginRaw); - const compressionMethod = dataView.getUint16(8, true); - const compressedSize = dataView.getUint32(18, true); - const uncompressedSize = dataView.getUint32(22, true); - const fileNameLength = dataView.getUint16(26, true); - const extraFieldLength = dataView.getUint16(28, true); - const headerSize = ZIP_ENTRY_HEADER_BEGIN_LENGTH + fileNameLength + extraFieldLength; - return { - offset, - compressionMethod, - compressedSize, - uncompressedSize, - headerSize, - }; -} -// Wrapper for Entry#getData() that unwraps ProgressEvent errors -async function zipGetData(entry, writer, options) { - try { - return await entry.getData(writer, options); - } - catch (e) { - if (e instanceof ProgressEvent && - e.type === "error" && - e.target !== null) { - throw e.target.error; - } - else { - throw e; - } - } -} - -const FILE_MAGIC = 0xed26ff3a; -const MAJOR_VERSION = 1; -const MINOR_VERSION = 0; -const FILE_HEADER_SIZE = 28; -const CHUNK_HEADER_SIZE = 12; -// AOSP libsparse uses 64 MiB chunks -const RAW_CHUNK_SIZE = 64 * 1024 * 1024; -class ImageError extends Error { - constructor(message) { - super(message); - this.name = "ImageError"; - } -} -var ChunkType; -(function (ChunkType) { - ChunkType[ChunkType["Raw"] = 51905] = "Raw"; - ChunkType[ChunkType["Fill"] = 51906] = "Fill"; - ChunkType[ChunkType["Skip"] = 51907] = "Skip"; - ChunkType[ChunkType["Crc32"] = 51908] = "Crc32"; -})(ChunkType || (ChunkType = {})); -class BlobBuilder { - constructor(type = "") { - this.type = type; - this.blob = new Blob([], { type: this.type }); - } - append(blob) { - this.blob = new Blob([this.blob, blob], { type: this.type }); - } - getBlob() { - return this.blob; - } -} -/** - * Returns a parsed version of the sparse image file header from the given buffer. - * - * @param {ArrayBuffer} buffer - Raw file header data. - * @returns {SparseHeader} Object containing the header information. - */ -function parseFileHeader(buffer) { - let view = new DataView(buffer); - let magic = view.getUint32(0, true); - if (magic !== FILE_MAGIC) { - return null; - } - // v1.0+ - let major = view.getUint16(4, true); - let minor = view.getUint16(6, true); - if (major !== MAJOR_VERSION || minor < MINOR_VERSION) { - throw new ImageError(`Unsupported sparse image version ${major}.${minor}`); - } - let fileHdrSize = view.getUint16(8, true); - let chunkHdrSize = view.getUint16(10, true); - if (fileHdrSize !== FILE_HEADER_SIZE || - chunkHdrSize !== CHUNK_HEADER_SIZE) { - throw new ImageError(`Invalid file header size ${fileHdrSize}, chunk header size ${chunkHdrSize}`); - } - let blockSize = view.getUint32(12, true); - if (blockSize % 4 !== 0) { - throw new ImageError(`Block size ${blockSize} is not a multiple of 4`); - } - return { - blockSize: blockSize, - blocks: view.getUint32(16, true), - chunks: view.getUint32(20, true), - crc32: view.getUint32(24, true), - }; -} -function parseChunkHeader(buffer) { - let view = new DataView(buffer); - // This isn't the same as what createImage takes. - // Further processing needs to be done on the chunks. - return { - type: view.getUint16(0, true), - /* 2: reserved, 16 bits */ - blocks: view.getUint32(4, true), - dataBytes: view.getUint32(8, true) - CHUNK_HEADER_SIZE, - data: null, // to be populated by consumer - }; -} -function calcChunksBlockSize(chunks) { - return chunks - .map((chunk) => chunk.blocks) - .reduce((total, c) => total + c, 0); -} -function calcChunksDataSize(chunks) { - return chunks - .map((chunk) => chunk.data.size) - .reduce((total, c) => total + c, 0); -} -function calcChunksSize(chunks) { - // 28-byte file header, 12-byte chunk headers - let overhead = FILE_HEADER_SIZE + CHUNK_HEADER_SIZE * chunks.length; - return overhead + calcChunksDataSize(chunks); -} -async function createImage(header, chunks) { - let blobBuilder = new BlobBuilder(); - let buffer = new ArrayBuffer(FILE_HEADER_SIZE); - let dataView = new DataView(buffer); - let arrayView = new Uint8Array(buffer); - dataView.setUint32(0, FILE_MAGIC, true); - // v1.0 - dataView.setUint16(4, MAJOR_VERSION, true); - dataView.setUint16(6, MINOR_VERSION, true); - dataView.setUint16(8, FILE_HEADER_SIZE, true); - dataView.setUint16(10, CHUNK_HEADER_SIZE, true); - // Match input parameters - dataView.setUint32(12, header.blockSize, true); - dataView.setUint32(16, header.blocks, true); - dataView.setUint32(20, chunks.length, true); - // We don't care about the CRC. AOSP docs specify that this should be a CRC32, - // but AOSP libsparse always sets 0 and puts the CRC in a final undocumented - // 0xCAC4 chunk instead. - dataView.setUint32(24, 0, true); - blobBuilder.append(new Blob([buffer])); - for (let chunk of chunks) { - buffer = new ArrayBuffer(CHUNK_HEADER_SIZE + chunk.data.size); - dataView = new DataView(buffer); - arrayView = new Uint8Array(buffer); - dataView.setUint16(0, chunk.type, true); - dataView.setUint16(2, 0, true); // reserved - dataView.setUint32(4, chunk.blocks, true); - dataView.setUint32(8, CHUNK_HEADER_SIZE + chunk.data.size, true); - let chunkArrayView = new Uint8Array(await readBlobAsBuffer(chunk.data)); - arrayView.set(chunkArrayView, CHUNK_HEADER_SIZE); - blobBuilder.append(new Blob([buffer])); - } - return blobBuilder.getBlob(); -} -/** - * Creates a sparse image from buffer containing raw image data. - * - * @param {Blob} blob - Blob containing the raw image data. - * @returns {Promise} Promise that resolves the blob containing the new sparse image. - */ -async function fromRaw(blob) { - let header = { - blockSize: 4096, - blocks: blob.size / 4096, - chunks: 1, - crc32: 0, - }; - let chunks = []; - while (blob.size > 0) { - let chunkSize = Math.min(blob.size, RAW_CHUNK_SIZE); - chunks.push({ - type: ChunkType.Raw, - blocks: chunkSize / header.blockSize, - data: blob.slice(0, chunkSize), - }); - blob = blob.slice(chunkSize); - } - return createImage(header, chunks); -} -/** - * Split a sparse image into smaller sparse images within the given size. - * This takes a Blob instead of an ArrayBuffer because it may process images - * larger than RAM. - * - * @param {Blob} blob - Blob containing the sparse image to split. - * @param {number} splitSize - Maximum size per split. - * @yields {Object} Data of the next split image and its output size in bytes. - */ -async function* splitBlob(blob, splitSize) { - logDebug(`Splitting ${blob.size}-byte sparse image into ${splitSize}-byte chunks`); - // Short-circuit if splitting isn't required - if (blob.size <= splitSize) { - logDebug("Blob fits in 1 payload, not splitting"); - yield { - data: await readBlobAsBuffer(blob), - bytes: blob.size, - }; - return; - } - let headerData = await readBlobAsBuffer(blob.slice(0, FILE_HEADER_SIZE)); - let header = parseFileHeader(headerData); - if (header === null) { - throw new ImageError("Blob is not a sparse image"); - } - // Remove CRC32 (if present), otherwise splitting will invalidate it - header.crc32 = 0; - blob = blob.slice(FILE_HEADER_SIZE); - let splitChunks = []; - let splitDataBytes = 0; - for (let i = 0; i < header.chunks; i++) { - let chunkHeaderData = await readBlobAsBuffer(blob.slice(0, CHUNK_HEADER_SIZE)); - let chunk = parseChunkHeader(chunkHeaderData); - chunk.data = blob.slice(CHUNK_HEADER_SIZE, CHUNK_HEADER_SIZE + chunk.dataBytes); - blob = blob.slice(CHUNK_HEADER_SIZE + chunk.dataBytes); - let bytesRemaining = splitSize - calcChunksSize(splitChunks); - logVerbose(` Chunk ${i}: type ${chunk.type}, ${chunk.dataBytes} bytes / ${chunk.blocks} blocks, ${bytesRemaining} bytes remaining`); - if (bytesRemaining >= chunk.dataBytes) { - // Read the chunk and add it - logVerbose(" Space is available, adding chunk"); - splitChunks.push(chunk); - // Track amount of data written on the output device, in bytes - splitDataBytes += chunk.blocks * header.blockSize; - } - else { - // Out of space, finish this split - // Blocks need to be calculated from chunk headers instead of going by size - // because FILL and SKIP chunks cover more blocks than the data they contain. - let splitBlocks = calcChunksBlockSize(splitChunks); - splitChunks.push({ - type: ChunkType.Skip, - blocks: header.blocks - splitBlocks, - data: new Blob([]), - dataBytes: 0, - }); - logVerbose(`Partition is ${header.blocks} blocks, used ${splitBlocks}, padded with ${header.blocks - splitBlocks}, finishing split with ${calcChunksBlockSize(splitChunks)} blocks`); - let splitImage = await createImage(header, splitChunks); - logDebug(`Finished ${splitImage.size}-byte split with ${splitChunks.length} chunks`); - yield { - data: await readBlobAsBuffer(splitImage), - bytes: splitDataBytes, - }; - // Start a new split. Every split is considered a full image by the - // bootloader, so we need to skip the *total* written blocks. - logVerbose(`Starting new split: skipping first ${splitBlocks} blocks and adding chunk`); - splitChunks = [ - { - type: ChunkType.Skip, - blocks: splitBlocks, - data: new Blob([]), - dataBytes: 0, - }, - chunk, - ]; - splitDataBytes = 0; - } - } - // Finish the final split if necessary - if (splitChunks.length > 0 && - (splitChunks.length > 1 || splitChunks[0].type !== ChunkType.Skip)) { - let splitImage = await createImage(header, splitChunks); - logDebug(`Finishing final ${splitImage.size}-byte split with ${splitChunks.length} chunks`); - yield { - data: await readBlobAsBuffer(splitImage), - bytes: splitDataBytes, - }; - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc. - * JZlib is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -// deno-lint-ignore-file no-this-alias prefer-const - -// Global - -const MAX_BITS$1 = 15; -const D_CODES = 30; -const BL_CODES = 19; - -const LENGTH_CODES = 29; -const LITERALS = 256; -const L_CODES = (LITERALS + 1 + LENGTH_CODES); -const HEAP_SIZE = (2 * L_CODES + 1); - -const END_BLOCK = 256; - -// Bit length codes must not exceed MAX_BL_BITS bits -const MAX_BL_BITS = 7; - -// repeat previous bit length 3-6 times (2 bits of repeat count) -const REP_3_6 = 16; - -// repeat a zero length 3-10 times (3 bits of repeat count) -const REPZ_3_10 = 17; - -// repeat a zero length 11-138 times (7 bits of repeat count) -const REPZ_11_138 = 18; - -// The lengths of the bit length codes are sent in order of decreasing -// probability, to avoid transmitting the lengths for unused bit -// length codes. - -const Buf_size = 8 * 2; - -// JZlib version : "1.0.2" -const Z_DEFAULT_COMPRESSION = -1; - -// compression strategy -const Z_FILTERED = 1; -const Z_HUFFMAN_ONLY = 2; -const Z_DEFAULT_STRATEGY = 0; - -const Z_NO_FLUSH$1 = 0; -const Z_PARTIAL_FLUSH = 1; -const Z_FULL_FLUSH = 3; -const Z_FINISH$1 = 4; - -const Z_OK$1 = 0; -const Z_STREAM_END$1 = 1; -const Z_NEED_DICT$1 = 2; -const Z_STREAM_ERROR$1 = -2; -const Z_DATA_ERROR$1 = -3; -const Z_BUF_ERROR$1 = -5; - -// Tree - -function extractArray(array) { - return flatArray(array.map(([length, value]) => (new Array(length)).fill(value, 0, length))); -} - -function flatArray(array) { - return array.reduce((a, b) => a.concat(Array.isArray(b) ? flatArray(b) : b), []); -} - -// see definition of array dist_code below -const _dist_code = [0, 1, 2, 3].concat(...extractArray([ - [2, 4], [2, 5], [4, 6], [4, 7], [8, 8], [8, 9], [16, 10], [16, 11], [32, 12], [32, 13], [64, 14], [64, 15], [2, 0], [1, 16], - [1, 17], [2, 18], [2, 19], [4, 20], [4, 21], [8, 22], [8, 23], [16, 24], [16, 25], [32, 26], [32, 27], [64, 28], [64, 29] -])); - -function Tree() { - const that = this; - - // dyn_tree; // the dynamic tree - // max_code; // largest code with non zero frequency - // stat_desc; // the corresponding static tree - - // Compute the optimal bit lengths for a tree and update the total bit - // length - // for the current block. - // IN assertion: the fields freq and dad are set, heap[heap_max] and - // above are the tree nodes sorted by increasing frequency. - // OUT assertions: the field len is set to the optimal bit length, the - // array bl_count contains the frequencies for each bit length. - // The length opt_len is updated; static_len is also updated if stree is - // not null. - function gen_bitlen(s) { - const tree = that.dyn_tree; - const stree = that.stat_desc.static_tree; - const extra = that.stat_desc.extra_bits; - const base = that.stat_desc.extra_base; - const max_length = that.stat_desc.max_length; - let h; // heap index - let n, m; // iterate over the tree elements - let bits; // bit length - let xbits; // extra bits - let f; // frequency - let overflow = 0; // number of elements with bit length too large - - for (bits = 0; bits <= MAX_BITS$1; bits++) - s.bl_count[bits] = 0; - - // In a first pass, compute the optimal bit lengths (which may - // overflow in the case of the bit length tree). - tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap - - for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1] = bits; - // We overwrite tree[n*2+1] which is no longer needed - - if (n > that.max_code) - continue; // not a leaf node - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) - xbits = extra[n - base]; - f = tree[n * 2]; - s.opt_len += f * (bits + xbits); - if (stree) - s.static_len += f * (stree[n * 2 + 1] + xbits); - } - if (overflow === 0) - return; - - // This happens for example on obj2 and pic of the Calgary corpus - // Find the first bit length which could increase: - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) - bits--; - s.bl_count[bits]--; // move one leaf down the tree - s.bl_count[bits + 1] += 2; // move one overflow item as its brother - s.bl_count[max_length]--; - // The brother of the overflow item also moves one step up, - // but this does not affect bl_count[max_length] - overflow -= 2; - } while (overflow > 0); - - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > that.max_code) - continue; - if (tree[m * 2 + 1] != bits) { - s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2]; - tree[m * 2 + 1] = bits; - } - n--; - } - } - } - - // Reverse the first len bits of a code, using straightforward code (a - // faster - // method would use a table) - // IN assertion: 1 <= len <= 15 - function bi_reverse(code, // the value to invert - len // its bit length - ) { - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; - } - - // Generate the codes for a given tree and bit counts (which need not be - // optimal). - // IN assertion: the array bl_count contains the bit length statistics for - // the given tree and the field len is set for all tree elements. - // OUT assertion: the field code is set for all tree elements of non - // zero code length. - function gen_codes(tree, // the tree to decorate - max_code, // largest code with non zero frequency - bl_count // number of codes at each bit length - ) { - const next_code = []; // next code value for each - // bit length - let code = 0; // running code value - let bits; // bit index - let n; // code index - let len; - - // The distribution counts are first used to generate the code values - // without bit reversal. - for (bits = 1; bits <= MAX_BITS$1; bits++) { - next_code[bits] = code = ((code + bl_count[bits - 1]) << 1); - } - - // Check that the bit counts in bl_count are consistent. The last code - // must be all ones. - // Assert (code + bl_count[MAX_BITS]-1 == (1<= 1; n--) - s.pqdownheap(tree, n); - - // Construct the Huffman tree by repeatedly combining the least two - // frequent nodes. - - node = elems; // next internal node of the tree - do { - // n = node of least frequency - n = s.heap[1]; - s.heap[1] = s.heap[s.heap_len--]; - s.pqdownheap(tree, 1); - m = s.heap[1]; // m = node of next least frequency - - s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency - s.heap[--s.heap_max] = m; - - // Create a new node father of n and m - tree[node * 2] = (tree[n * 2] + tree[m * 2]); - s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1; - tree[n * 2 + 1] = tree[m * 2 + 1] = node; - - // and insert the new node in the heap - s.heap[1] = node++; - s.pqdownheap(tree, 1); - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1]; - - // At this point, the fields freq and dad are set. We can now - // generate the bit lengths. - - gen_bitlen(s); - - // The field len is now set, we can generate the bit codes - gen_codes(tree, that.max_code, s.bl_count); - }; - -} - -Tree._length_code = [0, 1, 2, 3, 4, 5, 6, 7].concat(...extractArray([ - [2, 8], [2, 9], [2, 10], [2, 11], [4, 12], [4, 13], [4, 14], [4, 15], [8, 16], [8, 17], [8, 18], [8, 19], - [16, 20], [16, 21], [16, 22], [16, 23], [32, 24], [32, 25], [32, 26], [31, 27], [1, 28]])); - -Tree.base_length = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0]; - -Tree.base_dist = [0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, - 24576]; - -// Mapping from a distance to a distance code. dist is the distance - 1 and -// must not have side effects. _dist_code[256] and _dist_code[257] are never -// used. -Tree.d_code = function (dist) { - return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]); -}; - -// extra bits for each length code -Tree.extra_lbits = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]; - -// extra bits for each distance code -Tree.extra_dbits = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]; - -// extra bits for each bit length code -Tree.extra_blbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]; - -Tree.bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - -// StaticTree - -function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) { - const that = this; - that.static_tree = static_tree; - that.extra_bits = extra_bits; - that.extra_base = extra_base; - that.elems = elems; - that.max_length = max_length; -} - -const static_ltree2_first_part = [12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, - 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, - 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, - 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, - 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 19, 275, 147, 403, 83, 339, 211, 467, 51, 307, - 179, 435, 115, 371, 243, 499, 11, 267, 139, 395, 75, 331, 203, 459, 43, 299, 171, 427, 107, 363, 235, 491, 27, 283, 155, 411, 91, 347, 219, 475, - 59, 315, 187, 443, 123, 379, 251, 507, 7, 263, 135, 391, 71, 327, 199, 455, 39, 295, 167, 423, 103, 359, 231, 487, 23, 279, 151, 407, 87, 343, 215, - 471, 55, 311, 183, 439, 119, 375, 247, 503, 15, 271, 143, 399, 79, 335, 207, 463, 47, 303, 175, 431, 111, 367, 239, 495, 31, 287, 159, 415, 95, - 351, 223, 479, 63, 319, 191, 447, 127, 383, 255, 511, 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, 4, 68, 36, 100, 20, 84, 52, - 116, 3, 131, 67, 195, 35, 163, 99, 227]; -const static_ltree2_second_part = extractArray([[144, 8], [112, 9], [24, 7], [8, 8]]); -StaticTree.static_ltree = flatArray(static_ltree2_first_part.map((value, index) => [value, static_ltree2_second_part[index]])); - -const static_dtree_first_part = [0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23]; -const static_dtree_second_part = extractArray([[30, 5]]); -StaticTree.static_dtree = flatArray(static_dtree_first_part.map((value, index) => [value, static_dtree_second_part[index]])); - -StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS$1); - -StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS$1); - -StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS); - -// Deflate - -const MAX_MEM_LEVEL = 9; -const DEF_MEM_LEVEL = 8; - -function Config(good_length, max_lazy, nice_length, max_chain, func) { - const that = this; - that.good_length = good_length; - that.max_lazy = max_lazy; - that.nice_length = nice_length; - that.max_chain = max_chain; - that.func = func; -} - -const STORED$1 = 0; -const FAST = 1; -const SLOW = 2; -const config_table = [ - new Config(0, 0, 0, 0, STORED$1), - new Config(4, 4, 8, 4, FAST), - new Config(4, 5, 16, 8, FAST), - new Config(4, 6, 32, 32, FAST), - new Config(4, 4, 16, 16, SLOW), - new Config(8, 16, 32, 32, SLOW), - new Config(8, 16, 128, 128, SLOW), - new Config(8, 32, 128, 256, SLOW), - new Config(32, 128, 258, 1024, SLOW), - new Config(32, 258, 258, 4096, SLOW) -]; - -const z_errmsg = ["need dictionary", // Z_NEED_DICT - // 2 - "stream end", // Z_STREAM_END 1 - "", // Z_OK 0 - "", // Z_ERRNO (-1) - "stream error", // Z_STREAM_ERROR (-2) - "data error", // Z_DATA_ERROR (-3) - "", // Z_MEM_ERROR (-4) - "buffer error", // Z_BUF_ERROR (-5) - "",// Z_VERSION_ERROR (-6) - ""]; - -// block not completed, need more input or more output -const NeedMore = 0; - -// block flush performed -const BlockDone = 1; - -// finish started, need only more output at next deflate -const FinishStarted = 2; - -// finish done, accept no more input or output -const FinishDone = 3; - -// preset dictionary flag in zlib header -const PRESET_DICT$1 = 0x20; - -const INIT_STATE = 42; -const BUSY_STATE = 113; -const FINISH_STATE = 666; - -// The deflate compression method -const Z_DEFLATED$1 = 8; - -const STORED_BLOCK = 0; -const STATIC_TREES = 1; -const DYN_TREES = 2; - -const MIN_MATCH = 3; -const MAX_MATCH = 258; -const MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - -function smaller(tree, n, m, depth) { - const tn2 = tree[n * 2]; - const tm2 = tree[m * 2]; - return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m])); -} - -function Deflate() { - - const that = this; - let strm; // pointer back to this zlib stream - let status; // as the name implies - // pending_buf; // output still pending - let pending_buf_size; // size of pending_buf - // pending_out; // next pending byte to output to the stream - // pending; // nb of bytes in the pending buffer - - // dist_buf; // buffer for distances - // lc_buf; // buffer for literals or lengths - // To simplify the code, dist_buf and lc_buf have the same number of elements. - // To use different lengths, an extra flag array would be necessary. - - let last_flush; // value of flush param for previous deflate call - - let w_size; // LZ77 win size (32K by default) - let w_bits; // log2(w_size) (8..16) - let w_mask; // w_size - 1 - - let win; - // Sliding win. Input bytes are read into the second half of the win, - // and move to the first half later to keep a dictionary of at least wSize - // bytes. With this organization, matches are limited to a distance of - // wSize-MAX_MATCH bytes, but this ensures that IO is always - // performed with a length multiple of the block size. Also, it limits - // the win size to 64K, which is quite useful on MSDOS. - // To do: use the user input buffer as sliding win. - - let window_size; - // Actual size of win: 2*wSize, except when the user input buffer - // is directly used as sliding win. - - let prev; - // Link to older string with same hash index. To limit the size of this - // array to 64K, this link is maintained only for the last 32K strings. - // An index in this array is thus a win index modulo 32K. - - let head; // Heads of the hash chains or NIL. - - let ins_h; // hash index of string to be inserted - let hash_size; // number of elements in hash table - let hash_bits; // log2(hash_size) - let hash_mask; // hash_size-1 - - // Number of bits by which ins_h must be shifted at each input - // step. It must be such that after MIN_MATCH steps, the oldest - // byte no longer takes part in the hash key, that is: - // hash_shift * MIN_MATCH >= hash_bits - let hash_shift; - - // Window position at the beginning of the current output block. Gets - // negative when the win is moved backwards. - - let block_start; - - let match_length; // length of best match - let prev_match; // previous match - let match_available; // set if previous match exists - let strstart; // start of string to insert - let match_start; // start of matching string - let lookahead; // number of valid bytes ahead in win - - // Length of the best match at previous step. Matches not greater than this - // are discarded. This is used in the lazy match evaluation. - let prev_length; - - // To speed up deflation, hash chains are never searched beyond this - // length. A higher limit improves compression ratio but degrades the speed. - let max_chain_length; - - // Attempt to find a better match only when the current match is strictly - // smaller than this value. This mechanism is used only for compression - // levels >= 4. - let max_lazy_match; - - // Insert new strings in the hash table only if the match length is not - // greater than this length. This saves time but degrades compression. - // max_insert_length is used only for compression levels <= 3. - - let level; // compression level (1..9) - let strategy; // favor or force Huffman coding - - // Use a faster search when the previous match is longer than this - let good_match; - - // Stop searching when current match exceeds this - let nice_match; - - let dyn_ltree; // literal and length tree - let dyn_dtree; // distance tree - let bl_tree; // Huffman tree for bit lengths - - const l_desc = new Tree(); // desc for literal tree - const d_desc = new Tree(); // desc for distance tree - const bl_desc = new Tree(); // desc for bit length tree - - // that.heap_len; // number of elements in the heap - // that.heap_max; // element of largest frequency - // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - // The same heap array is used to build all trees. - - // Depth of each subtree used as tie breaker for trees of equal frequency - that.depth = []; - - // Size of match buffer for literals/lengths. There are 4 reasons for - // limiting lit_bufsize to 64K: - // - frequencies can be kept in 16 bit counters - // - if compression is not successful for the first block, all input - // data is still in the win so we can still emit a stored block even - // when input comes from standard input. (This can also be done for - // all blocks if lit_bufsize is not greater than 32K.) - // - if compression is not successful for a file smaller than 64K, we can - // even emit a stored file instead of a stored block (saving 5 bytes). - // This is applicable only for zip (not gzip or zlib). - // - creating new Huffman trees less frequently may not provide fast - // adaptation to changes in the input data statistics. (Take for - // example a binary file with poorly compressible code followed by - // a highly compressible string table.) Smaller buffer sizes give - // fast adaptation but have of course the overhead of transmitting - // trees more frequently. - // - I can't count above 4 - let lit_bufsize; - - let last_lit; // running index in dist_buf and lc_buf - - // that.opt_len; // bit length of current block with optimal trees - // that.static_len; // bit length of current block with static trees - let matches; // number of string matches in current block - let last_eob_len; // bit length of EOB code for last block - - // Output buffer. bits are inserted starting at the bottom (least - // significant bits). - let bi_buf; - - // Number of valid bits in bi_buf. All bits above the last valid bit - // are always zero. - let bi_valid; - - // number of codes at each bit length for an optimal tree - that.bl_count = []; - - // heap used to build the Huffman trees - that.heap = []; - - dyn_ltree = []; - dyn_dtree = []; - bl_tree = []; - - function lm_init() { - window_size = 2 * w_size; - - head[hash_size - 1] = 0; - for (let i = 0; i < hash_size - 1; i++) { - head[i] = 0; - } - - // Set the default configuration parameters: - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - - strstart = 0; - block_start = 0; - lookahead = 0; - match_length = prev_length = MIN_MATCH - 1; - match_available = 0; - ins_h = 0; - } - - function init_block() { - let i; - // Initialize the trees. - for (i = 0; i < L_CODES; i++) - dyn_ltree[i * 2] = 0; - for (i = 0; i < D_CODES; i++) - dyn_dtree[i * 2] = 0; - for (i = 0; i < BL_CODES; i++) - bl_tree[i * 2] = 0; - - dyn_ltree[END_BLOCK * 2] = 1; - that.opt_len = that.static_len = 0; - last_lit = matches = 0; - } - - // Initialize the tree data structures for a new zlib stream. - function tr_init() { - - l_desc.dyn_tree = dyn_ltree; - l_desc.stat_desc = StaticTree.static_l_desc; - - d_desc.dyn_tree = dyn_dtree; - d_desc.stat_desc = StaticTree.static_d_desc; - - bl_desc.dyn_tree = bl_tree; - bl_desc.stat_desc = StaticTree.static_bl_desc; - - bi_buf = 0; - bi_valid = 0; - last_eob_len = 8; // enough lookahead for inflate - - // Initialize the first block of the first file: - init_block(); - } - - // Restore the heap property by moving down the tree starting at node k, - // exchanging a node with the smallest of its two sons if necessary, - // stopping - // when the heap property is re-established (each father smaller than its - // two sons). - that.pqdownheap = function (tree, // the tree to restore - k // node to move down - ) { - const heap = that.heap; - const v = heap[k]; - let j = k << 1; // left son of k - while (j <= that.heap_len) { - // Set j to the smallest of the two sons: - if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) { - j++; - } - // Exit if v is smaller than both sons - if (smaller(tree, v, heap[j], that.depth)) - break; - - // Exchange v with the smallest son - heap[k] = heap[j]; - k = j; - // And continue down the tree, setting j to the left son of k - j <<= 1; - } - heap[k] = v; - }; - - // Scan a literal or distance tree to determine the frequencies of the codes - // in the bit length tree. - function scan_tree(tree,// the tree to be scanned - max_code // and its largest code of non zero frequency - ) { - let prevlen = -1; // last emitted length - let curlen; // length of current code - let nextlen = tree[0 * 2 + 1]; // length of next code - let count = 0; // repeat count of the current code - let max_count = 7; // max repeat count - let min_count = 4; // min repeat count - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1] = 0xffff; // guard - - for (let n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - bl_tree[curlen * 2] += count; - } else if (curlen !== 0) { - if (curlen != prevlen) - bl_tree[curlen * 2]++; - bl_tree[REP_3_6 * 2]++; - } else if (count <= 10) { - bl_tree[REPZ_3_10 * 2]++; - } else { - bl_tree[REPZ_11_138 * 2]++; - } - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } else if (curlen == nextlen) { - max_count = 6; - min_count = 3; - } else { - max_count = 7; - min_count = 4; - } - } - } - - // Construct the Huffman tree for the bit lengths and return the index in - // bl_order of the last bit length code to send. - function build_bl_tree() { - let max_blindex; // index of last bit length code of non zero freq - - // Determine the bit length frequencies for literal and distance trees - scan_tree(dyn_ltree, l_desc.max_code); - scan_tree(dyn_dtree, d_desc.max_code); - - // Build the bit length tree: - bl_desc.build_tree(that); - // opt_len now includes the length of the tree representations, except - // the lengths of the bit lengths codes and the 5+5+4 bits for the - // counts. - - // Determine the number of bit length codes to send. The pkzip format - // requires that at least 4 bit length codes be sent. (appnote.txt says - // 3 but the actual value used is 4.) - for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { - if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0) - break; - } - // Update opt_len to include the bit length tree and counts - that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - - return max_blindex; - } - - // Output a byte on the stream. - // IN assertion: there is enough room in pending_buf. - function put_byte(p) { - that.pending_buf[that.pending++] = p; - } - - function put_short(w) { - put_byte(w & 0xff); - put_byte((w >>> 8) & 0xff); - } - - function putShortMSB(b) { - put_byte((b >> 8) & 0xff); - put_byte((b & 0xff) & 0xff); - } - - function send_bits(value, length) { - let val; - const len = length; - if (bi_valid > Buf_size - len) { - val = value; - // bi_buf |= (val << bi_valid); - bi_buf |= ((val << bi_valid) & 0xffff); - put_short(bi_buf); - bi_buf = val >>> (Buf_size - bi_valid); - bi_valid += len - Buf_size; - } else { - // bi_buf |= (value) << bi_valid; - bi_buf |= (((value) << bi_valid) & 0xffff); - bi_valid += len; - } - } - - function send_code(c, tree) { - const c2 = c * 2; - send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff); - } - - // Send a literal or distance tree in compressed form, using the codes in - // bl_tree. - function send_tree(tree,// the tree to be sent - max_code // and its largest code of non zero frequency - ) { - let n; // iterates over all tree elements - let prevlen = -1; // last emitted length - let curlen; // length of current code - let nextlen = tree[0 * 2 + 1]; // length of next code - let count = 0; // repeat count of the current code - let max_count = 7; // max repeat count - let min_count = 4; // min repeat count - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { - send_code(curlen, bl_tree); - } while (--count !== 0); - } else if (curlen !== 0) { - if (curlen != prevlen) { - send_code(curlen, bl_tree); - count--; - } - send_code(REP_3_6, bl_tree); - send_bits(count - 3, 2); - } else if (count <= 10) { - send_code(REPZ_3_10, bl_tree); - send_bits(count - 3, 3); - } else { - send_code(REPZ_11_138, bl_tree); - send_bits(count - 11, 7); - } - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } else if (curlen == nextlen) { - max_count = 6; - min_count = 3; - } else { - max_count = 7; - min_count = 4; - } - } - } - - // Send the header for a block using dynamic Huffman trees: the counts, the - // lengths of the bit length codes, the literal tree and the distance tree. - // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - function send_all_trees(lcodes, dcodes, blcodes) { - let rank; // index in bl_order - - send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt - send_bits(dcodes - 1, 5); - send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt - for (rank = 0; rank < blcodes; rank++) { - send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3); - } - send_tree(dyn_ltree, lcodes - 1); // literal tree - send_tree(dyn_dtree, dcodes - 1); // distance tree - } - - // Flush the bit buffer, keeping at most 7 bits in it. - function bi_flush() { - if (bi_valid == 16) { - put_short(bi_buf); - bi_buf = 0; - bi_valid = 0; - } else if (bi_valid >= 8) { - put_byte(bi_buf & 0xff); - bi_buf >>>= 8; - bi_valid -= 8; - } - } - - // Send one empty static block to give enough lookahead for inflate. - // This takes 10 bits, of which 7 may remain in the bit buffer. - // The current inflate code requires 9 bits of lookahead. If the - // last two codes for the previous block (real code plus EOB) were coded - // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - // the last real code. In this case we send two empty static blocks instead - // of one. (There are no problems if the previous block is stored or fixed.) - // To simplify the code, we assume the worst case of last real code encoded - // on one bit only. - function _tr_align() { - send_bits(STATIC_TREES << 1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - - bi_flush(); - - // Of the 10 bits for the empty block, we have already sent - // (10 - bi_valid) bits. The lookahead for the last real code (before - // the EOB of the previous block) was thus at least one plus the length - // of the EOB plus what we have just sent of the empty static block. - if (1 + last_eob_len + 10 - bi_valid < 9) { - send_bits(STATIC_TREES << 1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - bi_flush(); - } - last_eob_len = 7; - } - - // Save the match info and tally the frequency counts. Return true if - // the current block must be flushed. - function _tr_tally(dist, // distance of matched string - lc // match length-MIN_MATCH or unmatched char (if dist==0) - ) { - let out_length, in_length, dcode; - that.dist_buf[last_lit] = dist; - that.lc_buf[last_lit] = lc & 0xff; - last_lit++; - - if (dist === 0) { - // lc is the unmatched char - dyn_ltree[lc * 2]++; - } else { - matches++; - // Here, lc is the match length - MIN_MATCH - dist--; // dist = match distance - 1 - dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++; - dyn_dtree[Tree.d_code(dist) * 2]++; - } - - if ((last_lit & 0x1fff) === 0 && level > 2) { - // Compute an upper bound for the compressed length - out_length = last_lit * 8; - in_length = strstart - block_start; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]); - } - out_length >>>= 3; - if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2)) - return true; - } - - return (last_lit == lit_bufsize - 1); - // We avoid equality with lit_bufsize because of wraparound at 64K - // on 16 bit machines and because stored blocks are restricted to - // 64K-1 bytes. - } - - // Send the block data compressed using the given Huffman trees - function compress_block(ltree, dtree) { - let dist; // distance of matched string - let lc; // match length or unmatched char (if dist === 0) - let lx = 0; // running index in dist_buf and lc_buf - let code; // the code to send - let extra; // number of extra bits to send - - if (last_lit !== 0) { - do { - dist = that.dist_buf[lx]; - lc = that.lc_buf[lx]; - lx++; - - if (dist === 0) { - send_code(lc, ltree); // send a literal byte - } else { - // Here, lc is the match length - MIN_MATCH - code = Tree._length_code[lc]; - - send_code(code + LITERALS + 1, ltree); // send the length - // code - extra = Tree.extra_lbits[code]; - if (extra !== 0) { - lc -= Tree.base_length[code]; - send_bits(lc, extra); // send the extra length bits - } - dist--; // dist is now the match distance - 1 - code = Tree.d_code(dist); - - send_code(code, dtree); // send the distance code - extra = Tree.extra_dbits[code]; - if (extra !== 0) { - dist -= Tree.base_dist[code]; - send_bits(dist, extra); // send the extra distance bits - } - } // literal or match pair ? - } while (lx < last_lit); - } - - send_code(END_BLOCK, ltree); - last_eob_len = ltree[END_BLOCK * 2 + 1]; - } - - // Flush the bit buffer and align the output on a byte boundary - function bi_windup() { - if (bi_valid > 8) { - put_short(bi_buf); - } else if (bi_valid > 0) { - put_byte(bi_buf & 0xff); - } - bi_buf = 0; - bi_valid = 0; - } - - // Copy a stored block, storing first the length and its - // one's complement if requested. - function copy_block(buf, // the input data - len, // its length - header // true if block header must be written - ) { - bi_windup(); // align on byte boundary - last_eob_len = 8; // enough lookahead for inflate - - if (header) { - put_short(len); - put_short(~len); - } - - that.pending_buf.set(win.subarray(buf, buf + len), that.pending); - that.pending += len; - } - - // Send a stored block - function _tr_stored_block(buf, // input block - stored_len, // length of input block - eof // true if this is the last block for a file - ) { - send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type - copy_block(buf, stored_len, true); // with header - } - - // Determine the best encoding for the current block: dynamic trees, static - // trees or store, and output the encoded block to the zip file. - function _tr_flush_block(buf, // input block, or NULL if too old - stored_len, // length of input block - eof // true if this is the last block for a file - ) { - let opt_lenb, static_lenb;// opt_len and static_len in bytes - let max_blindex = 0; // index of last bit length code of non zero freq - - // Build the Huffman trees unless a stored block is forced - if (level > 0) { - // Construct the literal and distance trees - l_desc.build_tree(that); - - d_desc.build_tree(that); - - // At this point, opt_len and static_len are the total bit lengths - // of - // the compressed block data, excluding the tree representations. - - // Build the bit length tree for the above two trees, and get the - // index - // in bl_order of the last bit length code to send. - max_blindex = build_bl_tree(); - - // Determine the best encoding. Compute first the block length in - // bytes - opt_lenb = (that.opt_len + 3 + 7) >>> 3; - static_lenb = (that.static_len + 3 + 7) >>> 3; - - if (static_lenb <= opt_lenb) - opt_lenb = static_lenb; - } else { - opt_lenb = static_lenb = stored_len + 5; // force a stored block - } - - if ((stored_len + 4 <= opt_lenb) && buf != -1) { - // 4: two words for the lengths - // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - // Otherwise we can't have processed more than WSIZE input bytes - // since - // the last block flush, because compression would have been - // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - // transform a block into a stored block. - _tr_stored_block(buf, stored_len, eof); - } else if (static_lenb == opt_lenb) { - send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3); - compress_block(StaticTree.static_ltree, StaticTree.static_dtree); - } else { - send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3); - send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1); - compress_block(dyn_ltree, dyn_dtree); - } - - // The above check is made mod 2^32, for files larger than 512 MB - // and uLong implemented on 32 bits. - - init_block(); - - if (eof) { - bi_windup(); - } - } - - function flush_block_only(eof) { - _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); - block_start = strstart; - strm.flush_pending(); - } - - // Fill the win when the lookahead becomes insufficient. - // Updates strstart and lookahead. - // - // IN assertion: lookahead < MIN_LOOKAHEAD - // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - // At least one byte has been read, or avail_in === 0; reads are - // performed for at least two bytes (required for the zip translate_eol - // option -- not supported here). - function fill_window() { - let n, m; - let p; - let more; // Amount of free space at the end of the win. - - do { - more = (window_size - lookahead - strstart); - - // Deal with !@#$% 64K limit: - if (more === 0 && strstart === 0 && lookahead === 0) { - more = w_size; - } else if (more == -1) { - // Very unlikely, but possible on 16 bit machine if strstart == - // 0 - // and lookahead == 1 (input done one byte at time) - more--; - - // If the win is almost full and there is insufficient - // lookahead, - // move the upper half to the lower one to make room in the - // upper half. - } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) { - win.set(win.subarray(w_size, w_size + w_size), 0); - - match_start -= w_size; - strstart -= w_size; // we now have strstart >= MAX_DIST - block_start -= w_size; - - // Slide the hash table (could be avoided with 32 bit values - // at the expense of memory usage). We slide even when level == - // 0 - // to keep the hash table consistent if we switch back to level - // > 0 - // later. (Using level 0 permanently is not an optimal usage of - // zlib, so we don't care about this pathological case.) - - n = hash_size; - p = n; - do { - m = (head[--p] & 0xffff); - head[p] = (m >= w_size ? m - w_size : 0); - } while (--n !== 0); - - n = w_size; - p = n; - do { - m = (prev[--p] & 0xffff); - prev[p] = (m >= w_size ? m - w_size : 0); - // If n is not on any hash chain, prev[n] is garbage but - // its value will never be used. - } while (--n !== 0); - more += w_size; - } - - if (strm.avail_in === 0) - return; - - // If there was no sliding: - // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - // more == window_size - lookahead - strstart - // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - // => more >= window_size - 2*WSIZE + 2 - // In the BIG_MEM or MMAP case (not yet supported), - // window_size == input_size + MIN_LOOKAHEAD && - // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - // Otherwise, window_size == 2*WSIZE so more >= 2. - // If there was sliding, more >= WSIZE. So in all cases, more >= 2. - - n = strm.read_buf(win, strstart + lookahead, more); - lookahead += n; - - // Initialize the hash value now that we have some input: - if (lookahead >= MIN_MATCH) { - ins_h = win[strstart] & 0xff; - ins_h = (((ins_h) << hash_shift) ^ (win[strstart + 1] & 0xff)) & hash_mask; - } - // If the whole input has less than MIN_MATCH bytes, ins_h is - // garbage, - // but this is not important since only literal bytes will be - // emitted. - } while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0); - } - - // Copy without compression as much as possible from the input stream, - // return - // the current block state. - // This function does not insert new strings in the dictionary since - // uncompressible data is probably not useful. This function is used - // only for the level=0 compression option. - // NOTE: this function should be optimized to avoid extra copying from - // win to pending_buf. - function deflate_stored(flush) { - // Stored blocks are limited to 0xffff bytes, pending_buf is limited - // to pending_buf_size, and each stored block has a 5 byte header: - - let max_block_size = 0xffff; - let max_start; - - if (max_block_size > pending_buf_size - 5) { - max_block_size = pending_buf_size - 5; - } - - // Copy as much as possible from input to output: - // eslint-disable-next-line no-constant-condition - while (true) { - // Fill the win as much as possible: - if (lookahead <= 1) { - fill_window(); - if (lookahead === 0 && flush == Z_NO_FLUSH$1) - return NeedMore; - if (lookahead === 0) - break; // flush the current block - } - - strstart += lookahead; - lookahead = 0; - - // Emit a stored block if pending_buf will be full: - max_start = block_start + max_block_size; - if (strstart === 0 || strstart >= max_start) { - // strstart === 0 is possible when wraparound on 16-bit machine - lookahead = (strstart - max_start); - strstart = max_start; - - flush_block_only(false); - if (strm.avail_out === 0) - return NeedMore; - - } - - // Flush if we may have to slide, otherwise block_start may become - // negative and the data will be gone: - if (strstart - block_start >= w_size - MIN_LOOKAHEAD) { - flush_block_only(false); - if (strm.avail_out === 0) - return NeedMore; - } - } - - flush_block_only(flush == Z_FINISH$1); - if (strm.avail_out === 0) - return (flush == Z_FINISH$1) ? FinishStarted : NeedMore; - - return flush == Z_FINISH$1 ? FinishDone : BlockDone; - } - - function longest_match(cur_match) { - let chain_length = max_chain_length; // max hash chain length - let scan = strstart; // current string - let match; // matched string - let len; // length of current match - let best_len = prev_length; // best match length so far - const limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; - let _nice_match = nice_match; - - // Stop when cur_match becomes <= limit. To simplify the code, - // we prevent matches with the string of win index 0. - - const wmask = w_mask; - - const strend = strstart + MAX_MATCH; - let scan_end1 = win[scan + best_len - 1]; - let scan_end = win[scan + best_len]; - - // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of - // 16. - // It is easy to get rid of this optimization if necessary. - - // Do not waste too much time if we already have a good match: - if (prev_length >= good_match) { - chain_length >>= 2; - } - - // Do not look for matches beyond the end of the input. This is - // necessary - // to make deflate deterministic. - if (_nice_match > lookahead) - _nice_match = lookahead; - - do { - match = cur_match; - - // Skip to next match if the match length cannot increase - // or if the match length is less than 2: - if (win[match + best_len] != scan_end || win[match + best_len - 1] != scan_end1 || win[match] != win[scan] - || win[++match] != win[scan + 1]) - continue; - - // The check at best_len-1 can be removed because it will be made - // again later. (This heuristic is not always a win.) - // It is not necessary to compare scan[2] and match[2] since they - // are always equal when the other bytes match, given that - // the hash keys are equal and that HASH_BITS >= 8. - scan += 2; - match++; - - // We check for insufficient lookahead only every 8th comparison; - // the 256th check will be made at strstart+258. - // eslint-disable-next-line no-empty - do { - // empty block - } while (win[++scan] == win[++match] && win[++scan] == win[++match] && win[++scan] == win[++match] - && win[++scan] == win[++match] && win[++scan] == win[++match] && win[++scan] == win[++match] - && win[++scan] == win[++match] && win[++scan] == win[++match] && scan < strend); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - match_start = cur_match; - best_len = len; - if (len >= _nice_match) - break; - scan_end1 = win[scan + best_len - 1]; - scan_end = win[scan + best_len]; - } - - } while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0); - - if (best_len <= lookahead) - return best_len; - return lookahead; - } - - // Compress as much as possible from the input stream, return the current - // block state. - // This function does not perform lazy evaluation of matches and inserts - // new strings in the dictionary only for unmatched strings or for short - // matches. It is used only for the fast compression options. - function deflate_fast(flush) { - // short hash_head = 0; // head of the hash chain - let hash_head = 0; // head of the hash chain - let bflush; // set if current block must be flushed - - // eslint-disable-next-line no-constant-condition - while (true) { - // Make sure that we always have enough lookahead, except - // at the end of the input file. We need MAX_MATCH bytes - // for the next match, plus MIN_MATCH bytes to insert the - // string following the next match. - if (lookahead < MIN_LOOKAHEAD) { - fill_window(); - if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH$1) { - return NeedMore; - } - if (lookahead === 0) - break; // flush the current block - } - - // Insert the string win[strstart .. strstart+2] in the - // dictionary, and set hash_head to the head of the hash chain: - if (lookahead >= MIN_MATCH) { - ins_h = (((ins_h) << hash_shift) ^ (win[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = strstart; - } - - // Find the longest match, discarding those <= prev_length. - // At this point we have always match_length < MIN_MATCH - - if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) { - // To simplify the code, we prevent matches with the string - // of win index 0 (in particular we have to avoid a match - // of the string with itself at the start of the input file). - if (strategy != Z_HUFFMAN_ONLY) { - match_length = longest_match(hash_head); - } - // longest_match() sets match_start - } - if (match_length >= MIN_MATCH) { - // check_match(strstart, match_start, match_length); - - bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH); - - lookahead -= match_length; - - // Insert new strings in the hash table only if the match length - // is not too large. This saves time but degrades compression. - if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) { - match_length--; // string at strstart already in hash table - do { - strstart++; - - ins_h = ((ins_h << hash_shift) ^ (win[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = strstart; - - // strstart never exceeds WSIZE-MAX_MATCH, so there are - // always MIN_MATCH bytes ahead. - } while (--match_length !== 0); - strstart++; - } else { - strstart += match_length; - match_length = 0; - ins_h = win[strstart] & 0xff; - - ins_h = (((ins_h) << hash_shift) ^ (win[strstart + 1] & 0xff)) & hash_mask; - // If lookahead < MIN_MATCH, ins_h is garbage, but it does - // not - // matter since it will be recomputed at next deflate call. - } - } else { - // No match, output a literal byte - - bflush = _tr_tally(0, win[strstart] & 0xff); - lookahead--; - strstart++; - } - if (bflush) { - - flush_block_only(false); - if (strm.avail_out === 0) - return NeedMore; - } - } - - flush_block_only(flush == Z_FINISH$1); - if (strm.avail_out === 0) { - if (flush == Z_FINISH$1) - return FinishStarted; - else - return NeedMore; - } - return flush == Z_FINISH$1 ? FinishDone : BlockDone; - } - - // Same as above, but achieves better compression. We use a lazy - // evaluation for matches: a match is finally adopted only if there is - // no better match at the next win position. - function deflate_slow(flush) { - // short hash_head = 0; // head of hash chain - let hash_head = 0; // head of hash chain - let bflush; // set if current block must be flushed - let max_insert; - - // Process the input block. - // eslint-disable-next-line no-constant-condition - while (true) { - // Make sure that we always have enough lookahead, except - // at the end of the input file. We need MAX_MATCH bytes - // for the next match, plus MIN_MATCH bytes to insert the - // string following the next match. - - if (lookahead < MIN_LOOKAHEAD) { - fill_window(); - if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH$1) { - return NeedMore; - } - if (lookahead === 0) - break; // flush the current block - } - - // Insert the string win[strstart .. strstart+2] in the - // dictionary, and set hash_head to the head of the hash chain: - - if (lookahead >= MIN_MATCH) { - ins_h = (((ins_h) << hash_shift) ^ (win[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = strstart; - } - - // Find the longest match, discarding those <= prev_length. - prev_length = match_length; - prev_match = match_start; - match_length = MIN_MATCH - 1; - - if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) { - // To simplify the code, we prevent matches with the string - // of win index 0 (in particular we have to avoid a match - // of the string with itself at the start of the input file). - - if (strategy != Z_HUFFMAN_ONLY) { - match_length = longest_match(hash_head); - } - // longest_match() sets match_start - - if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) { - - // If prev_match is also MIN_MATCH, match_start is garbage - // but we will ignore the current match anyway. - match_length = MIN_MATCH - 1; - } - } - - // If there was a match at the previous step and the current - // match is not better, output the previous match: - if (prev_length >= MIN_MATCH && match_length <= prev_length) { - max_insert = strstart + lookahead - MIN_MATCH; - // Do not insert strings in hash table beyond this. - - // check_match(strstart-1, prev_match, prev_length); - - bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); - - // Insert in hash table all strings up to the end of the match. - // strstart-1 and strstart are already inserted. If there is not - // enough lookahead, the last two strings are not inserted in - // the hash table. - lookahead -= prev_length - 1; - prev_length -= 2; - do { - if (++strstart <= max_insert) { - ins_h = (((ins_h) << hash_shift) ^ (win[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = strstart; - } - } while (--prev_length !== 0); - match_available = 0; - match_length = MIN_MATCH - 1; - strstart++; - - if (bflush) { - flush_block_only(false); - if (strm.avail_out === 0) - return NeedMore; - } - } else if (match_available !== 0) { - - // If there was no match at the previous position, output a - // single literal. If there was a match but the current match - // is longer, truncate the previous match to a single literal. - - bflush = _tr_tally(0, win[strstart - 1] & 0xff); - - if (bflush) { - flush_block_only(false); - } - strstart++; - lookahead--; - if (strm.avail_out === 0) - return NeedMore; - } else { - // There is no previous match to compare with, wait for - // the next step to decide. - - match_available = 1; - strstart++; - lookahead--; - } - } - - if (match_available !== 0) { - bflush = _tr_tally(0, win[strstart - 1] & 0xff); - match_available = 0; - } - flush_block_only(flush == Z_FINISH$1); - - if (strm.avail_out === 0) { - if (flush == Z_FINISH$1) - return FinishStarted; - else - return NeedMore; - } - - return flush == Z_FINISH$1 ? FinishDone : BlockDone; - } - - function deflateReset(strm) { - strm.total_in = strm.total_out = 0; - strm.msg = null; // - - that.pending = 0; - that.pending_out = 0; - - status = BUSY_STATE; - - last_flush = Z_NO_FLUSH$1; - - tr_init(); - lm_init(); - return Z_OK$1; - } - - that.deflateInit = function (strm, _level, bits, _method, memLevel, _strategy) { - if (!_method) - _method = Z_DEFLATED$1; - if (!memLevel) - memLevel = DEF_MEM_LEVEL; - if (!_strategy) - _strategy = Z_DEFAULT_STRATEGY; - - // byte[] my_version=ZLIB_VERSION; - - // - // if (!version || version[0] != my_version[0] - // || stream_size != sizeof(z_stream)) { - // return Z_VERSION_ERROR; - // } - - strm.msg = null; - - if (_level == Z_DEFAULT_COMPRESSION) - _level = 6; - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED$1 || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0 - || _strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR$1; - } - - strm.dstate = that; - - w_bits = bits; - w_size = 1 << w_bits; - w_mask = w_size - 1; - - hash_bits = memLevel + 7; - hash_size = 1 << hash_bits; - hash_mask = hash_size - 1; - hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - win = new Uint8Array(w_size * 2); - prev = []; - head = []; - - lit_bufsize = 1 << (memLevel + 6); // 16K elements by default - - that.pending_buf = new Uint8Array(lit_bufsize * 4); - pending_buf_size = lit_bufsize * 4; - - that.dist_buf = new Uint16Array(lit_bufsize); - that.lc_buf = new Uint8Array(lit_bufsize); - - level = _level; - - strategy = _strategy; - - return deflateReset(strm); - }; - - that.deflateEnd = function () { - if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { - return Z_STREAM_ERROR$1; - } - // Deallocate in reverse order of allocations: - that.lc_buf = null; - that.dist_buf = null; - that.pending_buf = null; - head = null; - prev = null; - win = null; - // free - that.dstate = null; - return status == BUSY_STATE ? Z_DATA_ERROR$1 : Z_OK$1; - }; - - that.deflateParams = function (strm, _level, _strategy) { - let err = Z_OK$1; - - if (_level == Z_DEFAULT_COMPRESSION) { - _level = 6; - } - if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR$1; - } - - if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) { - // Flush the last buffer: - err = strm.deflate(Z_PARTIAL_FLUSH); - } - - if (level != _level) { - level = _level; - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - } - strategy = _strategy; - return err; - }; - - that.deflateSetDictionary = function (_strm, dictionary, dictLength) { - let length = dictLength; - let n, index = 0; - - if (!dictionary || status != INIT_STATE) - return Z_STREAM_ERROR$1; - - if (length < MIN_MATCH) - return Z_OK$1; - if (length > w_size - MIN_LOOKAHEAD) { - length = w_size - MIN_LOOKAHEAD; - index = dictLength - length; // use the tail of the dictionary - } - win.set(dictionary.subarray(index, index + length), 0); - - strstart = length; - block_start = length; - - // Insert all strings in the hash table (except for the last two bytes). - // s->lookahead stays null, so s->ins_h will be recomputed at the next - // call of fill_window. - - ins_h = win[0] & 0xff; - ins_h = (((ins_h) << hash_shift) ^ (win[1] & 0xff)) & hash_mask; - - for (n = 0; n <= length - MIN_MATCH; n++) { - ins_h = (((ins_h) << hash_shift) ^ (win[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - prev[n & w_mask] = head[ins_h]; - head[ins_h] = n; - } - return Z_OK$1; - }; - - that.deflate = function (_strm, flush) { - let i, header, level_flags, old_flush, bstate; - - if (flush > Z_FINISH$1 || flush < 0) { - return Z_STREAM_ERROR$1; - } - - if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH$1)) { - _strm.msg = z_errmsg[Z_NEED_DICT$1 - (Z_STREAM_ERROR$1)]; - return Z_STREAM_ERROR$1; - } - if (_strm.avail_out === 0) { - _strm.msg = z_errmsg[Z_NEED_DICT$1 - (Z_BUF_ERROR$1)]; - return Z_BUF_ERROR$1; - } - - strm = _strm; // just in case - old_flush = last_flush; - last_flush = flush; - - // Write the zlib header - if (status == INIT_STATE) { - header = (Z_DEFLATED$1 + ((w_bits - 8) << 4)) << 8; - level_flags = ((level - 1) & 0xff) >> 1; - - if (level_flags > 3) - level_flags = 3; - header |= (level_flags << 6); - if (strstart !== 0) - header |= PRESET_DICT$1; - header += 31 - (header % 31); - - status = BUSY_STATE; - putShortMSB(header); - } - - // Flush as much pending output as possible - if (that.pending !== 0) { - strm.flush_pending(); - if (strm.avail_out === 0) { - // console.log(" avail_out==0"); - // Since avail_out is 0, deflate will be called again with - // more output space, but possibly with both pending and - // avail_in equal to zero. There won't be anything to do, - // but this is not an error situation so make sure we - // return OK instead of BUF_ERROR at next call of deflate: - last_flush = -1; - return Z_OK$1; - } - - // Make sure there is something to do and avoid duplicate - // consecutive - // flushes. For repeated and useless calls with Z_FINISH, we keep - // returning Z_STREAM_END instead of Z_BUFF_ERROR. - } else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH$1) { - strm.msg = z_errmsg[Z_NEED_DICT$1 - (Z_BUF_ERROR$1)]; - return Z_BUF_ERROR$1; - } - - // User must not provide more input after the first FINISH: - if (status == FINISH_STATE && strm.avail_in !== 0) { - _strm.msg = z_errmsg[Z_NEED_DICT$1 - (Z_BUF_ERROR$1)]; - return Z_BUF_ERROR$1; - } - - // Start a new block or continue the current one. - if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH$1 && status != FINISH_STATE)) { - bstate = -1; - switch (config_table[level].func) { - case STORED$1: - bstate = deflate_stored(flush); - break; - case FAST: - bstate = deflate_fast(flush); - break; - case SLOW: - bstate = deflate_slow(flush); - break; - } - - if (bstate == FinishStarted || bstate == FinishDone) { - status = FINISH_STATE; - } - if (bstate == NeedMore || bstate == FinishStarted) { - if (strm.avail_out === 0) { - last_flush = -1; // avoid BUF_ERROR next call, see above - } - return Z_OK$1; - // If flush != Z_NO_FLUSH && avail_out === 0, the next call - // of deflate should use the same flush parameter to make sure - // that the flush is complete. So we don't have to output an - // empty block here, this will be done at next call. This also - // ensures that for a very small output buffer, we emit at most - // one empty block. - } - - if (bstate == BlockDone) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(); - } else { // FULL_FLUSH or SYNC_FLUSH - _tr_stored_block(0, 0, false); - // For a full flush, this empty block will be recognized - // as a special marker by inflate_sync(). - if (flush == Z_FULL_FLUSH) { - // state.head[s.hash_size-1]=0; - for (i = 0; i < hash_size/*-1*/; i++) - // forget history - head[i] = 0; - } - } - strm.flush_pending(); - if (strm.avail_out === 0) { - last_flush = -1; // avoid BUF_ERROR at next call, see above - return Z_OK$1; - } - } - } - - if (flush != Z_FINISH$1) - return Z_OK$1; - return Z_STREAM_END$1; - }; -} - -// ZStream - -function ZStream$1() { - const that = this; - that.next_in_index = 0; - that.next_out_index = 0; - // that.next_in; // next input byte - that.avail_in = 0; // number of bytes available at next_in - that.total_in = 0; // total nb of input bytes read so far - // that.next_out; // next output byte should be put there - that.avail_out = 0; // remaining free space at next_out - that.total_out = 0; // total nb of bytes output so far - // that.msg; - // that.dstate; -} - -ZStream$1.prototype = { - deflateInit(level, bits) { - const that = this; - that.dstate = new Deflate(); - if (!bits) - bits = MAX_BITS$1; - return that.dstate.deflateInit(that, level, bits); - }, - - deflate(flush) { - const that = this; - if (!that.dstate) { - return Z_STREAM_ERROR$1; - } - return that.dstate.deflate(that, flush); - }, - - deflateEnd() { - const that = this; - if (!that.dstate) - return Z_STREAM_ERROR$1; - const ret = that.dstate.deflateEnd(); - that.dstate = null; - return ret; - }, - - deflateParams(level, strategy) { - const that = this; - if (!that.dstate) - return Z_STREAM_ERROR$1; - return that.dstate.deflateParams(that, level, strategy); - }, - - deflateSetDictionary(dictionary, dictLength) { - const that = this; - if (!that.dstate) - return Z_STREAM_ERROR$1; - return that.dstate.deflateSetDictionary(that, dictionary, dictLength); - }, - - // Read a new buffer from the current input stream, update the - // total number of bytes read. All deflate() input goes through - // this function so some applications may wish to modify it to avoid - // allocating a large strm->next_in buffer and copying from it. - // (See also flush_pending()). - read_buf(buf, start, size) { - const that = this; - let len = that.avail_in; - if (len > size) - len = size; - if (len === 0) - return 0; - that.avail_in -= len; - buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start); - that.next_in_index += len; - that.total_in += len; - return len; - }, - - // Flush as much pending output as possible. All deflate() output goes - // through this function so some applications may wish to modify it - // to avoid allocating a large strm->next_out buffer and copying into it. - // (See also read_buf()). - flush_pending() { - const that = this; - let len = that.dstate.pending; - - if (len > that.avail_out) - len = that.avail_out; - if (len === 0) - return; - - // if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index - // || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index + - // len)) { - // console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " + - // that.next_out_index + ", " + len); - // console.log("avail_out=" + that.avail_out); - // } - - that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index); - - that.next_out_index += len; - that.dstate.pending_out += len; - that.total_out += len; - that.avail_out -= len; - that.dstate.pending -= len; - if (that.dstate.pending === 0) { - that.dstate.pending_out = 0; - } - } -}; - -// Deflate - -function ZipDeflate(options) { - const that = this; - const z = new ZStream$1(); - const bufsize = getMaximumCompressedSize(options && options.chunkSize ? options.chunkSize : 64 * 1024); - const flush = Z_NO_FLUSH$1; - const buf = new Uint8Array(bufsize); - let level = options ? options.level : Z_DEFAULT_COMPRESSION; - if (typeof level == "undefined") - level = Z_DEFAULT_COMPRESSION; - z.deflateInit(level); - z.next_out = buf; - - that.append = function (data, onprogress) { - let err, array, lastIndex = 0, bufferIndex = 0, bufferSize = 0; - const buffers = []; - if (!data.length) - return; - z.next_in_index = 0; - z.next_in = data; - z.avail_in = data.length; - do { - z.next_out_index = 0; - z.avail_out = bufsize; - err = z.deflate(flush); - if (err != Z_OK$1) - throw new Error("deflating: " + z.msg); - if (z.next_out_index) - if (z.next_out_index == bufsize) - buffers.push(new Uint8Array(buf)); - else - buffers.push(buf.slice(0, z.next_out_index)); - bufferSize += z.next_out_index; - if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) { - onprogress(z.next_in_index); - lastIndex = z.next_in_index; - } - } while (z.avail_in > 0 || z.avail_out === 0); - if (buffers.length > 1) { - array = new Uint8Array(bufferSize); - buffers.forEach(function (chunk) { - array.set(chunk, bufferIndex); - bufferIndex += chunk.length; - }); - } else { - array = buffers[0] || new Uint8Array(); - } - return array; - }; - that.flush = function () { - let err, array, bufferIndex = 0, bufferSize = 0; - const buffers = []; - do { - z.next_out_index = 0; - z.avail_out = bufsize; - err = z.deflate(Z_FINISH$1); - if (err != Z_STREAM_END$1 && err != Z_OK$1) - throw new Error("deflating: " + z.msg); - if (bufsize - z.avail_out > 0) - buffers.push(buf.slice(0, z.next_out_index)); - bufferSize += z.next_out_index; - } while (z.avail_in > 0 || z.avail_out === 0); - z.deflateEnd(); - array = new Uint8Array(bufferSize); - buffers.forEach(function (chunk) { - array.set(chunk, bufferIndex); - bufferIndex += chunk.length; - }); - return array; - }; -} - -function getMaximumCompressedSize(uncompressedSize) { - return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1)); -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc. - * JZlib is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -// deno-lint-ignore-file no-this-alias prefer-const - -// Global - -const MAX_BITS = 15; - -const Z_OK = 0; -const Z_STREAM_END = 1; -const Z_NEED_DICT = 2; -const Z_STREAM_ERROR = -2; -const Z_DATA_ERROR = -3; -const Z_MEM_ERROR = -4; -const Z_BUF_ERROR = -5; - -const inflate_mask = [0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, - 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff]; - -const MANY = 1440; - -// JZlib version : "1.0.2" -const Z_NO_FLUSH = 0; -const Z_FINISH = 4; - -// InfTree -const fixed_bl = 9; -const fixed_bd = 5; - -const fixed_tl = [96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, - 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, - 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, - 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, - 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, - 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, - 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, - 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, - 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, - 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, - 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, - 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, - 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, - 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, - 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, - 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, - 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, - 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, - 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, - 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, - 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, - 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, - 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, - 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, - 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, - 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, - 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, - 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, - 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, - 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, - 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, - 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, - 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, - 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, - 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, - 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, - 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255]; -const fixed_td = [80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, - 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, - 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577]; - -// Tables for deflate from PKZIP's appnote.txt. -const cplens = [ // Copy lengths for literal codes 257..285 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0]; - -// see note #13 above about 258 -const cplext = [ // Extra bits for literal codes 257..285 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid -]; - -const cpdist = [ // Copy offsets for distance codes 0..29 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577]; - -const cpdext = [ // Extra bits for distance codes - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]; - -// If BMAX needs to be larger than 16, then h and x[] should be uLong. -const BMAX = 15; // maximum bit length of any code - -function InfTree() { - const that = this; - - let hn; // hufts used in space - let v; // work area for huft_build - let c; // bit length count table - let r; // table entry for structure assignment - let u; // table stack - let x; // bit offsets, then code stack - - function huft_build(b, // code lengths in bits (all assumed <= - // BMAX) - bindex, n, // number of codes (assumed <= 288) - s, // number of simple-valued codes (0..s-1) - d, // list of base values for non-simple codes - e, // list of extra bits for non-simple codes - t, // result: starting table - m, // maximum lookup bits, returns actual - hp,// space for trees - hn,// hufts used in space - v // working area: values in order of bit length - ) { - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, - // Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in - // this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set - // of - // lengths), or Z_MEM_ERROR if not enough memory. - - let a; // counter for codes of length k - let f; // i repeats in table every f entries - let g; // maximum code length - let h; // table level - let i; // counter, current code - let j; // counter - let k; // number of bits in current code - let l; // bits per table (returned in m) - let mask; // (1 << w) - 1, to avoid cc -O bug on HP - let p; // pointer into c[], b[], or v[] - let q; // points to current table - let w; // bits before this table == (l * h) - let xp; // pointer into x - let y; // number of dummy codes added - let z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; - i = n; - do { - c[b[bindex + p]]++; - p++; - i--; // assume all entries <= BMAX - } while (i !== 0); - - if (c[0] == n) { // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if (c[j] !== 0) - break; - k = j; // minimum code length - if (l < j) { - l = j; - } - for (i = BMAX; i !== 0; i--) { - if (c[i] !== 0) - break; - } - g = i; // maximum code length - if (l > i) { - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1) { - if ((y -= c[j]) < 0) { - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0) { - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; - xp = 2; - while (--i !== 0) { // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; - p = 0; - do { - if ((j = b[bindex + p]) !== 0) { - v[x[j]++] = i; - } - p++; - } while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++) { - a = c[k]; - while (a-- !== 0) { - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l) { - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table - // too few codes for - // k-w bit table - f -= a + 1; // deduct codes from patterns left - xp = k; - if (j < z) { - while (++j < z) { // try smaller tables up to z bits - if ((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY) { // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - u[h] = q = /* hp+ */hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if (h !== 0) { - x[h] = i; // save pattern for backing up - r[0] = /* (byte) */j; // bits in this table - r[1] = /* (byte) */l; // bits to dump before this table - j = i >>> (w - l); - r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table - hp.set(r, (u[h - 1] + j) * 3); - // to - // last - // table - } else { - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - r[1] = /* (byte) */(k - w); - if (p >= n) { - r[0] = 128 + 64; // out of values--invalid code - } else if (v[p] < s) { - r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is - // end-of-block - r[2] = v[p++]; // simple code is just the value - } else { - r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look - // up in lists - r[2] = d[v[p++] - s]; - } - - // fill code-like entries with r - f = 1 << (k - w); - for (j = i >>> w; j < z; j += f) { - hp.set(r, (q + j) * 3); - } - - // backwards increment the k-bit code i - for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) { - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]) { - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK; - } - - function initWorkArea(vsize) { - let i; - if (!hn) { - hn = []; // []; //new Array(1); - v = []; // new Array(vsize); - c = new Int32Array(BMAX + 1); // new Array(BMAX + 1); - r = []; // new Array(3); - u = new Int32Array(BMAX); // new Array(BMAX); - x = new Int32Array(BMAX + 1); // new Array(BMAX + 1); - } - if (v.length < vsize) { - v = []; // new Array(vsize); - } - for (i = 0; i < vsize; i++) { - v[i] = 0; - } - for (i = 0; i < BMAX + 1; i++) { - c[i] = 0; - } - for (i = 0; i < 3; i++) { - r[i] = 0; - } - // for(int i=0; i 257)) { - if (result == Z_DATA_ERROR) { - z.msg = "oversubscribed distance tree"; - } else if (result == Z_BUF_ERROR) { - z.msg = "incomplete distance tree"; - result = Z_DATA_ERROR; - } else if (result != Z_MEM_ERROR) { - z.msg = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - }; - -} - -InfTree.inflate_trees_fixed = function (bl, // literal desired/actual bit depth - bd, // distance desired/actual bit depth - tl,// literal/length tree result - td// distance tree result -) { - bl[0] = fixed_bl; - bd[0] = fixed_bd; - tl[0] = fixed_tl; - td[0] = fixed_td; - return Z_OK; -}; - -// InfCodes - -// waiting for "i:"=input, -// "o:"=output, -// "x:"=nothing -const START = 0; // x: set up for LEN -const LEN = 1; // i: get length/literal/eob next -const LENEXT = 2; // i: getting length extra (have base) -const DIST = 3; // i: get distance next -const DISTEXT = 4;// i: getting distance extra -const COPY = 5; // o: copying bytes in win, waiting -// for space -const LIT = 6; // o: got literal, waiting for output -// space -const WASH = 7; // o: got eob, possibly still output -// waiting -const END = 8; // x: got eob and all data flushed -const BADCODE = 9;// x: got error - -function InfCodes() { - const that = this; - - let mode; // current inflate_codes mode - - // mode dependent information - let len = 0; - - let tree; // pointer into tree - let tree_index = 0; - let need = 0; // bits needed - - let lit = 0; - - // if EXT or COPY, where and how much - let get = 0; // bits to get for extra - let dist = 0; // distance back to copy from - - let lbits = 0; // ltree bits decoded per branch - let dbits = 0; // dtree bits decoder per branch - let ltree; // literal/length/eob tree - let ltree_index = 0; // literal/length/eob tree - let dtree; // distance tree - let dtree_index = 0; // distance tree - - // Called with number of bytes left to write in win at least 258 - // (the maximum string length) and number of input bytes available - // at least ten. The ten bytes are six bytes for the longest length/ - // distance pair plus four bytes for overloading the bit buffer. - - function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) { - let t; // temporary pointer - let tp; // temporary pointer - let tp_index; // temporary pointer - let e; // extra bits or operation - let b; // bit buffer - let k; // bits in bit buffer - let p; // input data pointer - let n; // bytes available there - let q; // output win write pointer - let m; // bytes to end of win or read pointer - let ml; // mask for literal/length tree - let md; // mask for distance tree - let c; // bytes to copy - let d; // distance back to copy from - let r; // copy source pointer - - let tp_index_t_3; // (tp_index+t)*3 - - // load input, output, bit values - p = z.next_in_index; - n = z.avail_in; - b = s.bitb; - k = s.bitk; - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - // initialize masks - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - // do until not enough input or output space for fast loop - do { // assume called with m >= 258 && n >= 10 - // get literal/length code - while (k < (20)) { // max bits for literal/length code - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - t = b & ml; - tp = tl; - tp_index = tl_index; - tp_index_t_3 = (tp_index + t) * 3; - if ((e = tp[tp_index_t_3]) === 0) { - b >>= (tp[tp_index_t_3 + 1]); - k -= (tp[tp_index_t_3 + 1]); - - s.win[q++] = /* (byte) */tp[tp_index_t_3 + 2]; - m--; - continue; - } - do { - - b >>= (tp[tp_index_t_3 + 1]); - k -= (tp[tp_index_t_3 + 1]); - - if ((e & 16) !== 0) { - e &= 15; - c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]); - - b >>= e; - k -= e; - - // decode distance base of block to copy - while (k < (15)) { // max bits for distance code - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - t = b & md; - tp = td; - tp_index = td_index; - tp_index_t_3 = (tp_index + t) * 3; - e = tp[tp_index_t_3]; - - do { - - b >>= (tp[tp_index_t_3 + 1]); - k -= (tp[tp_index_t_3 + 1]); - - if ((e & 16) !== 0) { - // get extra bits to add to distance base - e &= 15; - while (k < (e)) { // get extra bits (up to 13) - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); - - b >>= (e); - k -= (e); - - // do the copy - m -= c; - if (q >= d) { // offset before dest - // just copy - r = q - d; - if (q - r > 0 && 2 > (q - r)) { - s.win[q++] = s.win[r++]; // minimum - // count is - // three, - s.win[q++] = s.win[r++]; // so unroll - // loop a - // little - c -= 2; - } else { - s.win.set(s.win.subarray(r, r + 2), q); - q += 2; - r += 2; - c -= 2; - } - } else { // else offset after destination - r = q - d; - do { - r += s.end; // force pointer in win - } while (r < 0); // covers invalid distances - e = s.end - r; - if (c > e) { // if source crosses, - c -= e; // wrapped copy - if (q - r > 0 && e > (q - r)) { - do { - s.win[q++] = s.win[r++]; - } while (--e !== 0); - } else { - s.win.set(s.win.subarray(r, r + e), q); - q += e; - r += e; - e = 0; - } - r = 0; // copy rest from start of win - } - - } - - // copy all or what's left - if (q - r > 0 && c > (q - r)) { - do { - s.win[q++] = s.win[r++]; - } while (--c !== 0); - } else { - s.win.set(s.win.subarray(r, r + c), q); - q += c; - r += c; - c = 0; - } - break; - } else if ((e & 64) === 0) { - t += tp[tp_index_t_3 + 2]; - t += (b & inflate_mask[e]); - tp_index_t_3 = (tp_index + t) * 3; - e = tp[tp_index_t_3]; - } else { - z.msg = "invalid distance code"; - - c = z.avail_in - n; - c = (k >> 3) < c ? k >> 3 : c; - n += c; - p -= c; - k -= c << 3; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - - return Z_DATA_ERROR; - } - // eslint-disable-next-line no-constant-condition - } while (true); - break; - } - - if ((e & 64) === 0) { - t += tp[tp_index_t_3 + 2]; - t += (b & inflate_mask[e]); - tp_index_t_3 = (tp_index + t) * 3; - if ((e = tp[tp_index_t_3]) === 0) { - - b >>= (tp[tp_index_t_3 + 1]); - k -= (tp[tp_index_t_3 + 1]); - - s.win[q++] = /* (byte) */tp[tp_index_t_3 + 2]; - m--; - break; - } - } else if ((e & 32) !== 0) { - - c = z.avail_in - n; - c = (k >> 3) < c ? k >> 3 : c; - n += c; - p -= c; - k -= c << 3; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - - return Z_STREAM_END; - } else { - z.msg = "invalid literal/length code"; - - c = z.avail_in - n; - c = (k >> 3) < c ? k >> 3 : c; - n += c; - p -= c; - k -= c << 3; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - - return Z_DATA_ERROR; - } - // eslint-disable-next-line no-constant-condition - } while (true); - } while (m >= 258 && n >= 10); - - // not enough input or output--restore pointers and return - c = z.avail_in - n; - c = (k >> 3) < c ? k >> 3 : c; - n += c; - p -= c; - k -= c << 3; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - - return Z_OK; - } - - that.init = function (bl, bd, tl, tl_index, td, td_index) { - mode = START; - lbits = /* (byte) */bl; - dbits = /* (byte) */bd; - ltree = tl; - ltree_index = tl_index; - dtree = td; - dtree_index = td_index; - tree = null; - }; - - that.proc = function (s, z, r) { - let j; // temporary storage - let tindex; // temporary pointer - let e; // extra bits or operation - let b = 0; // bit buffer - let k = 0; // bits in bit buffer - let p = 0; // input data pointer - let n; // bytes available there - let q; // output win write pointer - let m; // bytes to end of win or read pointer - let f; // pointer to copy strings from - - // copy input/output information to locals (UPDATE macro restores) - p = z.next_in_index; - n = z.avail_in; - b = s.bitb; - k = s.bitk; - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - // process input and output based on current state - // eslint-disable-next-line no-constant-condition - while (true) { - switch (mode) { - // waiting for "i:"=input, "o:"=output, "x:"=nothing - case START: // x: set up for LEN - if (m >= 258 && n >= 10) { - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); - - p = z.next_in_index; - n = z.avail_in; - b = s.bitb; - k = s.bitk; - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - if (r != Z_OK) { - mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } - need = lbits; - tree = ltree; - tree_index = ltree_index; - - mode = LEN; - /* falls through */ - case LEN: // i: get length/literal/eob next - j = need; - - while (k < (j)) { - if (n !== 0) - r = Z_OK; - else { - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - tindex = (tree_index + (b & inflate_mask[j])) * 3; - - b >>>= (tree[tindex + 1]); - k -= (tree[tindex + 1]); - - e = tree[tindex]; - - if (e === 0) { // literal - lit = tree[tindex + 2]; - mode = LIT; - break; - } - if ((e & 16) !== 0) { // length - get = e & 15; - len = tree[tindex + 2]; - mode = LENEXT; - break; - } - if ((e & 64) === 0) { // next table - need = e; - tree_index = tindex / 3 + tree[tindex + 2]; - break; - } - if ((e & 32) !== 0) { // end of block - mode = WASH; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - - case LENEXT: // i: getting length extra (have base) - j = get; - - while (k < (j)) { - if (n !== 0) - r = Z_OK; - else { - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - len += (b & inflate_mask[j]); - - b >>= j; - k -= j; - - need = dbits; - tree = dtree; - tree_index = dtree_index; - mode = DIST; - /* falls through */ - case DIST: // i: get distance next - j = need; - - while (k < (j)) { - if (n !== 0) - r = Z_OK; - else { - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - tindex = (tree_index + (b & inflate_mask[j])) * 3; - - b >>= tree[tindex + 1]; - k -= tree[tindex + 1]; - - e = (tree[tindex]); - if ((e & 16) !== 0) { // distance - get = e & 15; - dist = tree[tindex + 2]; - mode = DISTEXT; - break; - } - if ((e & 64) === 0) { // next table - need = e; - tree_index = tindex / 3 + tree[tindex + 2]; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid distance code"; - r = Z_DATA_ERROR; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - - case DISTEXT: // i: getting distance extra - j = get; - - while (k < (j)) { - if (n !== 0) - r = Z_OK; - else { - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - dist += (b & inflate_mask[j]); - - b >>= j; - k -= j; - - mode = COPY; - /* falls through */ - case COPY: // o: copying bytes in win, waiting for space - f = q - dist; - while (f < 0) { // modulo win size-"while" instead - f += s.end; // of "if" handles invalid distances - } - while (len !== 0) { - - if (m === 0) { - if (q == s.end && s.read !== 0) { - q = 0; - m = q < s.read ? s.read - q - 1 : s.end - q; - } - if (m === 0) { - s.write = q; - r = s.inflate_flush(z, r); - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - if (q == s.end && s.read !== 0) { - q = 0; - m = q < s.read ? s.read - q - 1 : s.end - q; - } - - if (m === 0) { - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - } - } - - s.win[q++] = s.win[f++]; - m--; - - if (f == s.end) - f = 0; - len--; - } - mode = START; - break; - case LIT: // o: got literal, waiting for output space - if (m === 0) { - if (q == s.end && s.read !== 0) { - q = 0; - m = q < s.read ? s.read - q - 1 : s.end - q; - } - if (m === 0) { - s.write = q; - r = s.inflate_flush(z, r); - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - if (q == s.end && s.read !== 0) { - q = 0; - m = q < s.read ? s.read - q - 1 : s.end - q; - } - if (m === 0) { - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - } - } - r = Z_OK; - - s.win[q++] = /* (byte) */lit; - m--; - - mode = START; - break; - case WASH: // o: got eob, possibly more output - if (k > 7) { // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - s.write = q; - r = s.inflate_flush(z, r); - q = s.write; - m = q < s.read ? s.read - q - 1 : s.end - q; - - if (s.read != s.write) { - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - mode = END; - /* falls through */ - case END: - r = Z_STREAM_END; - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - - case BADCODE: // x: got error - - r = Z_DATA_ERROR; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - - default: - r = Z_STREAM_ERROR; - - s.bitb = b; - s.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - s.write = q; - return s.inflate_flush(z, r); - } - } - }; - - that.free = function () { - // ZFREE(z, c); - }; - -} - -// InfBlocks - -// Table for deflate from PKZIP's appnote.txt. -const border = [ // Order of the bit length code lengths - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - -const TYPE = 0; // get type bits (3, including end bit) -const LENS = 1; // get lengths for stored -const STORED = 2;// processing stored block -const TABLE = 3; // get table lengths -const BTREE = 4; // get bit lengths tree for a dynamic -// block -const DTREE = 5; // get length, distance trees for a -// dynamic block -const CODES = 6; // processing fixed or dynamic block -const DRY = 7; // output remaining win bytes -const DONELOCKS = 8; // finished last block, done -const BADBLOCKS = 9; // ot a data error--stuck here - -function InfBlocks(z, w) { - const that = this; - - let mode = TYPE; // current inflate_block mode - - let left = 0; // if STORED, bytes left to copy - - let table = 0; // table lengths (14 bits) - let index = 0; // index into blens (or border) - let blens; // bit lengths of codes - const bb = [0]; // bit length tree depth - const tb = [0]; // bit length decoding tree - - const codes = new InfCodes(); // if CODES, current state - - let last = 0; // true if this block is the last block - - let hufts = new Int32Array(MANY * 3); // single malloc for tree space - const check = 0; // check on output - const inftree = new InfTree(); - - that.bitk = 0; // bits in bit buffer - that.bitb = 0; // bit buffer - that.win = new Uint8Array(w); // sliding win - that.end = w; // one byte after sliding win - that.read = 0; // win read pointer - that.write = 0; // win write pointer - - that.reset = function (z, c) { - if (c) - c[0] = check; - // if (mode == BTREE || mode == DTREE) { - // } - if (mode == CODES) { - codes.free(z); - } - mode = TYPE; - that.bitk = 0; - that.bitb = 0; - that.read = that.write = 0; - }; - - that.reset(z, null); - - // copy as much as possible from the sliding win to the output area - that.inflate_flush = function (z, r) { - let n; - let p; - let q; - - // local copies of source and destination pointers - p = z.next_out_index; - q = that.read; - - // compute number of bytes to copy as far as end of win - n = /* (int) */((q <= that.write ? that.write : that.end) - q); - if (n > z.avail_out) - n = z.avail_out; - if (n !== 0 && r == Z_BUF_ERROR) - r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // copy as far as end of win - z.next_out.set(that.win.subarray(q, q + n), p); - p += n; - q += n; - - // see if more to copy at beginning of win - if (q == that.end) { - // wrap pointers - q = 0; - if (that.write == that.end) - that.write = 0; - - // compute bytes to copy - n = that.write - q; - if (n > z.avail_out) - n = z.avail_out; - if (n !== 0 && r == Z_BUF_ERROR) - r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // copy - z.next_out.set(that.win.subarray(q, q + n), p); - p += n; - q += n; - } - - // update pointers - z.next_out_index = p; - that.read = q; - - // done - return r; - }; - - that.proc = function (z, r) { - let t; // temporary storage - let b; // bit buffer - let k; // bits in bit buffer - let p; // input data pointer - let n; // bytes available there - let q; // output win write pointer - let m; // bytes to end of win or read pointer - - let i; - - // copy input/output information to locals (UPDATE macro restores) - // { - p = z.next_in_index; - n = z.avail_in; - b = that.bitb; - k = that.bitk; - // } - // { - q = that.write; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - // } - - // process input based on current state - // DEBUG dtree - // eslint-disable-next-line no-constant-condition - while (true) { - let bl, bd, tl, td, bl_, bd_, tl_, td_; - switch (mode) { - case TYPE: - - while (k < (3)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - t = /* (int) */(b & 7); - last = t & 1; - - switch (t >>> 1) { - case 0: // stored - // { - b >>>= (3); - k -= (3); - // } - t = k & 7; // go to byte boundary - - // { - b >>>= (t); - k -= (t); - // } - mode = LENS; // get length of stored block - break; - case 1: // fixed - // { - bl = []; // new Array(1); - bd = []; // new Array(1); - tl = [[]]; // new Array(1); - td = [[]]; // new Array(1); - - InfTree.inflate_trees_fixed(bl, bd, tl, td); - codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); - // } - - // { - b >>>= (3); - k -= (3); - // } - - mode = CODES; - break; - case 2: // dynamic - - // { - b >>>= (3); - k -= (3); - // } - - mode = TABLE; - break; - case 3: // illegal - - // { - b >>>= (3); - k -= (3); - // } - mode = BADBLOCKS; - z.msg = "invalid block type"; - r = Z_DATA_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - break; - case LENS: - - while (k < (32)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) { - mode = BADBLOCKS; - z.msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - left = (b & 0xffff); - b = k = 0; // dump bits - mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE); - break; - case STORED: - if (n === 0) { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - - if (m === 0) { - if (q == that.end && that.read !== 0) { - q = 0; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - } - if (m === 0) { - that.write = q; - r = that.inflate_flush(z, r); - q = that.write; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - if (q == that.end && that.read !== 0) { - q = 0; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - } - if (m === 0) { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - } - } - r = Z_OK; - - t = left; - if (t > n) - t = n; - if (t > m) - t = m; - that.win.set(z.read_buf(p, t), q); - p += t; - n -= t; - q += t; - m -= t; - if ((left -= t) !== 0) - break; - mode = last !== 0 ? DRY : TYPE; - break; - case TABLE: - - while (k < (14)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - table = t = (b & 0x3fff); - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { - mode = BADBLOCKS; - z.msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (!blens || blens.length < t) { - blens = []; // new Array(t); - } else { - for (i = 0; i < t; i++) { - blens[i] = 0; - } - } - - // { - b >>>= (14); - k -= (14); - // } - - index = 0; - mode = BTREE; - /* falls through */ - case BTREE: - while (index < 4 + (table >>> 10)) { - while (k < (3)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - blens[border[index++]] = b & 7; - - // { - b >>>= (3); - k -= (3); - // } - } - - while (index < 19) { - blens[border[index++]] = 0; - } - - bb[0] = 7; - t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); - if (t != Z_OK) { - r = t; - if (r == Z_DATA_ERROR) { - blens = null; - mode = BADBLOCKS; - } - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - - index = 0; - mode = DTREE; - /* falls through */ - case DTREE: - // eslint-disable-next-line no-constant-condition - while (true) { - t = table; - if (index >= 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) { - break; - } - - let j, c; - - t = bb[0]; - - while (k < (t)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - // if (tb[0] == -1) { - // System.err.println("null..."); - // } - - t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; - c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; - - if (c < 16) { - b >>>= (t); - k -= (t); - blens[index++] = c; - } else { // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while (k < (t + i)) { - if (n !== 0) { - r = Z_OK; - } else { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - n--; - b |= (z.read_byte(p++) & 0xff) << k; - k += 8; - } - - b >>>= (t); - k -= (t); - - j += (b & inflate_mask[i]); - - b >>>= (i); - k -= (i); - - i = index; - t = table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { - blens = null; - mode = BADBLOCKS; - z.msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - - c = c == 16 ? blens[i - 1] : 0; - do { - blens[i++] = c; - } while (--j !== 0); - index = i; - } - } - - tb[0] = -1; - // { - bl_ = []; // new Array(1); - bd_ = []; // new Array(1); - tl_ = []; // new Array(1); - td_ = []; // new Array(1); - bl_[0] = 9; // must be <= 9 for lookahead assumptions - bd_[0] = 6; // must be <= 9 for lookahead assumptions - - t = table; - t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z); - - if (t != Z_OK) { - if (t == Z_DATA_ERROR) { - blens = null; - mode = BADBLOCKS; - } - r = t; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0]); - // } - mode = CODES; - /* falls through */ - case CODES: - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - - if ((r = codes.proc(that, z, r)) != Z_STREAM_END) { - return that.inflate_flush(z, r); - } - r = Z_OK; - codes.free(z); - - p = z.next_in_index; - n = z.avail_in; - b = that.bitb; - k = that.bitk; - q = that.write; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - - if (last === 0) { - mode = TYPE; - break; - } - mode = DRY; - /* falls through */ - case DRY: - that.write = q; - r = that.inflate_flush(z, r); - q = that.write; - m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); - if (that.read != that.write) { - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - mode = DONELOCKS; - /* falls through */ - case DONELOCKS: - r = Z_STREAM_END; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - case BADBLOCKS: - r = Z_DATA_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - - default: - r = Z_STREAM_ERROR; - - that.bitb = b; - that.bitk = k; - z.avail_in = n; - z.total_in += p - z.next_in_index; - z.next_in_index = p; - that.write = q; - return that.inflate_flush(z, r); - } - } - }; - - that.free = function (z) { - that.reset(z, null); - that.win = null; - hufts = null; - // ZFREE(z, s); - }; - - that.set_dictionary = function (d, start, n) { - that.win.set(d.subarray(start, start + n), 0); - that.read = that.write = n; - }; - - // Returns true if inflate is currently at the end of a block generated - // by Z_SYNC_FLUSH or Z_FULL_FLUSH. - that.sync_point = function () { - return mode == LENS ? 1 : 0; - }; - -} - -// Inflate - -// preset dictionary flag in zlib header -const PRESET_DICT = 0x20; - -const Z_DEFLATED = 8; - -const METHOD = 0; // waiting for method byte -const FLAG = 1; // waiting for flag byte -const DICT4 = 2; // four dictionary check bytes to go -const DICT3 = 3; // three dictionary check bytes to go -const DICT2 = 4; // two dictionary check bytes to go -const DICT1 = 5; // one dictionary check byte to go -const DICT0 = 6; // waiting for inflateSetDictionary -const BLOCKS = 7; // decompressing blocks -const DONE = 12; // finished check, done -const BAD = 13; // got an error--stay here - -const mark = [0, 0, 0xff, 0xff]; - -function Inflate() { - const that = this; - - that.mode = 0; // current inflate mode - - // mode dependent information - that.method = 0; // if FLAGS, method byte - - // if CHECK, check values to compare - that.was = [0]; // new Array(1); // computed check value - that.need = 0; // stream check value - - // if BAD, inflateSync's marker bytes count - that.marker = 0; - - // mode independent information - that.wbits = 0; // log2(win size) (8..15, defaults to 15) - - // this.blocks; // current inflate_blocks state - - function inflateReset(z) { - if (!z || !z.istate) - return Z_STREAM_ERROR; - - z.total_in = z.total_out = 0; - z.msg = null; - z.istate.mode = BLOCKS; - z.istate.blocks.reset(z, null); - return Z_OK; - } - - that.inflateEnd = function (z) { - if (that.blocks) - that.blocks.free(z); - that.blocks = null; - // ZFREE(z, z->state); - return Z_OK; - }; - - that.inflateInit = function (z, w) { - z.msg = null; - that.blocks = null; - - // set win size - if (w < 8 || w > 15) { - that.inflateEnd(z); - return Z_STREAM_ERROR; - } - that.wbits = w; - - z.istate.blocks = new InfBlocks(z, 1 << w); - - // reset state - inflateReset(z); - return Z_OK; - }; - - that.inflate = function (z, f) { - let r; - let b; - - if (!z || !z.istate || !z.next_in) - return Z_STREAM_ERROR; - const istate = z.istate; - f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; - r = Z_BUF_ERROR; - // eslint-disable-next-line no-constant-condition - while (true) { - switch (istate.mode) { - case METHOD: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - if (((istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) { - istate.mode = BAD; - z.msg = "unknown compression method"; - istate.marker = 5; // can't try inflateSync - break; - } - if ((istate.method >> 4) + 8 > istate.wbits) { - istate.mode = BAD; - z.msg = "invalid win size"; - istate.marker = 5; // can't try inflateSync - break; - } - istate.mode = FLAG; - /* falls through */ - case FLAG: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - b = (z.read_byte(z.next_in_index++)) & 0xff; - - if ((((istate.method << 8) + b) % 31) !== 0) { - istate.mode = BAD; - z.msg = "incorrect header check"; - istate.marker = 5; // can't try inflateSync - break; - } - - if ((b & PRESET_DICT) === 0) { - istate.mode = BLOCKS; - break; - } - istate.mode = DICT4; - /* falls through */ - case DICT4: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000; - istate.mode = DICT3; - /* falls through */ - case DICT3: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000; - istate.mode = DICT2; - /* falls through */ - case DICT2: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00; - istate.mode = DICT1; - /* falls through */ - case DICT1: - - if (z.avail_in === 0) - return r; - r = f; - - z.avail_in--; - z.total_in++; - istate.need += (z.read_byte(z.next_in_index++) & 0xff); - istate.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - istate.mode = BAD; - z.msg = "need dictionary"; - istate.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - - r = istate.blocks.proc(z, r); - if (r == Z_DATA_ERROR) { - istate.mode = BAD; - istate.marker = 0; // can try inflateSync - break; - } - if (r == Z_OK) { - r = f; - } - if (r != Z_STREAM_END) { - return r; - } - r = f; - istate.blocks.reset(z, istate.was); - istate.mode = DONE; - /* falls through */ - case DONE: - z.avail_in = 0; - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - } - }; - - that.inflateSetDictionary = function (z, dictionary, dictLength) { - let index = 0, length = dictLength; - if (!z || !z.istate || z.istate.mode != DICT0) - return Z_STREAM_ERROR; - const istate = z.istate; - if (length >= (1 << istate.wbits)) { - length = (1 << istate.wbits) - 1; - index = dictLength - length; - } - istate.blocks.set_dictionary(dictionary, index, length); - istate.mode = BLOCKS; - return Z_OK; - }; - - that.inflateSync = function (z) { - let n; // number of bytes to look at - let p; // pointer to bytes - let m; // number of marker bytes found in a row - let r, w; // temporaries to save total_in and total_out - - // set up - if (!z || !z.istate) - return Z_STREAM_ERROR; - const istate = z.istate; - if (istate.mode != BAD) { - istate.mode = BAD; - istate.marker = 0; - } - if ((n = z.avail_in) === 0) - return Z_BUF_ERROR; - p = z.next_in_index; - m = istate.marker; - - // search - while (n !== 0 && m < 4) { - if (z.read_byte(p) == mark[m]) { - m++; - } else if (z.read_byte(p) !== 0) { - m = 0; - } else { - m = 4 - m; - } - p++; - n--; - } - - // restore - z.total_in += p - z.next_in_index; - z.next_in_index = p; - z.avail_in = n; - istate.marker = m; - - // return no joy or set up to restart on a new block - if (m != 4) { - return Z_DATA_ERROR; - } - r = z.total_in; - w = z.total_out; - inflateReset(z); - z.total_in = r; - z.total_out = w; - istate.mode = BLOCKS; - return Z_OK; - }; - - // Returns true if inflate is currently at the end of a block generated - // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - // implementation to provide an additional safety check. PPP uses - // Z_SYNC_FLUSH - // but removes the length bytes of the resulting empty stored block. When - // decompressing, PPP checks that at the end of input packet, inflate is - // waiting for these length bytes. - that.inflateSyncPoint = function (z) { - if (!z || !z.istate || !z.istate.blocks) - return Z_STREAM_ERROR; - return z.istate.blocks.sync_point(); - }; -} - -// ZStream - -function ZStream() { -} - -ZStream.prototype = { - inflateInit(bits) { - const that = this; - that.istate = new Inflate(); - if (!bits) - bits = MAX_BITS; - return that.istate.inflateInit(that, bits); - }, - - inflate(f) { - const that = this; - if (!that.istate) - return Z_STREAM_ERROR; - return that.istate.inflate(that, f); - }, - - inflateEnd() { - const that = this; - if (!that.istate) - return Z_STREAM_ERROR; - const ret = that.istate.inflateEnd(that); - that.istate = null; - return ret; - }, - - inflateSync() { - const that = this; - if (!that.istate) - return Z_STREAM_ERROR; - return that.istate.inflateSync(that); - }, - inflateSetDictionary(dictionary, dictLength) { - const that = this; - if (!that.istate) - return Z_STREAM_ERROR; - return that.istate.inflateSetDictionary(that, dictionary, dictLength); - }, - read_byte(start) { - const that = this; - return that.next_in[start]; - }, - read_buf(start, size) { - const that = this; - return that.next_in.subarray(start, start + size); - } -}; - -// Inflater - -function ZipInflate(options) { - const that = this; - const z = new ZStream(); - const bufsize = options && options.chunkSize ? Math.floor(options.chunkSize * 2) : 128 * 1024; - const flush = Z_NO_FLUSH; - const buf = new Uint8Array(bufsize); - let nomoreinput = false; - - z.inflateInit(); - z.next_out = buf; - - that.append = function (data, onprogress) { - const buffers = []; - let err, array, lastIndex = 0, bufferIndex = 0, bufferSize = 0; - if (data.length === 0) - return; - z.next_in_index = 0; - z.next_in = data; - z.avail_in = data.length; - do { - z.next_out_index = 0; - z.avail_out = bufsize; - if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it - z.next_in_index = 0; - nomoreinput = true; - } - err = z.inflate(flush); - if (nomoreinput && (err === Z_BUF_ERROR)) { - if (z.avail_in !== 0) - throw new Error("inflating: bad input"); - } else if (err !== Z_OK && err !== Z_STREAM_END) - throw new Error("inflating: " + z.msg); - if ((nomoreinput || err === Z_STREAM_END) && (z.avail_in === data.length)) - throw new Error("inflating: bad input"); - if (z.next_out_index) - if (z.next_out_index === bufsize) - buffers.push(new Uint8Array(buf)); - else - buffers.push(buf.slice(0, z.next_out_index)); - bufferSize += z.next_out_index; - if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) { - onprogress(z.next_in_index); - lastIndex = z.next_in_index; - } - } while (z.avail_in > 0 || z.avail_out === 0); - if (buffers.length > 1) { - array = new Uint8Array(bufferSize); - buffers.forEach(function (chunk) { - array.set(chunk, bufferIndex); - bufferIndex += chunk.length; - }); - } else { - array = buffers[0] || new Uint8Array(); - } - return array; - }; - that.flush = function () { - z.inflateEnd(); - }; -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const MAX_32_BITS = 0xffffffff; -const MAX_16_BITS = 0xffff; -const COMPRESSION_METHOD_DEFLATE = 0x08; -const COMPRESSION_METHOD_STORE = 0x00; -const COMPRESSION_METHOD_AES = 0x63; - -const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50; -const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50; -const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50; -const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50; -const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50; -const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = 0x07064b50; -const END_OF_CENTRAL_DIR_LENGTH = 22; -const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH = 20; -const ZIP64_END_OF_CENTRAL_DIR_LENGTH = 56; - -const EXTRAFIELD_TYPE_ZIP64 = 0x0001; -const EXTRAFIELD_TYPE_AES = 0x9901; -const EXTRAFIELD_TYPE_NTFS = 0x000a; -const EXTRAFIELD_TYPE_NTFS_TAG1 = 0x0001; -const EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP = 0x5455; -const EXTRAFIELD_TYPE_UNICODE_PATH = 0x7075; -const EXTRAFIELD_TYPE_UNICODE_COMMENT = 0x6375; - -const BITFLAG_ENCRYPTED = 0x01; -const BITFLAG_LEVEL = 0x06; -const BITFLAG_DATA_DESCRIPTOR = 0x0008; -const BITFLAG_LANG_ENCODING_FLAG = 0x0800; -const FILE_ATTR_MSDOS_DIR_MASK = 0x10; - -const DIRECTORY_SIGNATURE = "/"; - -const UNDEFINED_VALUE = undefined; -const UNDEFINED_TYPE$1 = "undefined"; -const FUNCTION_TYPE$1 = "function"; - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -class StreamAdapter { - - constructor(Codec) { - return class extends TransformStream { - constructor(_format, options) { - const codec = new Codec(options); - super({ - transform(chunk, controller) { - controller.enqueue(codec.append(chunk)); - }, - flush(controller) { - const chunk = codec.flush(); - if (chunk) { - controller.enqueue(chunk); - } - } - }); - } - }; - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const MINIMUM_CHUNK_SIZE = 64; -let maxWorkers = 2; -try { - if (typeof navigator != UNDEFINED_TYPE$1 && navigator.hardwareConcurrency) { - maxWorkers = navigator.hardwareConcurrency; - } -} catch (_error) { - // ignored -} -const DEFAULT_CONFIGURATION = { - chunkSize: 512 * 1024, - maxWorkers, - terminateWorkerTimeout: 5000, - useWebWorkers: true, - useCompressionStream: true, - workerScripts: UNDEFINED_VALUE, - CompressionStreamNative: typeof CompressionStream != UNDEFINED_TYPE$1 && CompressionStream, - DecompressionStreamNative: typeof DecompressionStream != UNDEFINED_TYPE$1 && DecompressionStream -}; - -const config = Object.assign({}, DEFAULT_CONFIGURATION); - -function getConfiguration() { - return config; -} - -function getChunkSize(config) { - return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE); -} - -function configure(configuration) { - const { - baseURL, - chunkSize, - maxWorkers, - terminateWorkerTimeout, - useCompressionStream, - useWebWorkers, - Deflate, - Inflate, - CompressionStream, - DecompressionStream, - workerScripts - } = configuration; - setIfDefined("baseURL", baseURL); - setIfDefined("chunkSize", chunkSize); - setIfDefined("maxWorkers", maxWorkers); - setIfDefined("terminateWorkerTimeout", terminateWorkerTimeout); - setIfDefined("useCompressionStream", useCompressionStream); - setIfDefined("useWebWorkers", useWebWorkers); - if (Deflate) { - config.CompressionStream = new StreamAdapter(Deflate); - } - if (Inflate) { - config.DecompressionStream = new StreamAdapter(Inflate); - } - setIfDefined("CompressionStream", CompressionStream); - setIfDefined("DecompressionStream", DecompressionStream); - if (workerScripts !== UNDEFINED_VALUE) { - const { deflate, inflate } = workerScripts; - if (deflate || inflate) { - if (!config.workerScripts) { - config.workerScripts = {}; - } - } - if (deflate) { - if (!Array.isArray(deflate)) { - throw new Error("workerScripts.deflate must be an array"); - } - config.workerScripts.deflate = deflate; - } - if (inflate) { - if (!Array.isArray(inflate)) { - throw new Error("workerScripts.inflate must be an array"); - } - config.workerScripts.inflate = inflate; - } - } -} - -function setIfDefined(propertyName, propertyValue) { - if (propertyValue !== UNDEFINED_VALUE) { - config[propertyName] = propertyValue; - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const table$1 = { - "application": { - "andrew-inset": "ez", - "annodex": "anx", - "atom+xml": "atom", - "atomcat+xml": "atomcat", - "atomserv+xml": "atomsrv", - "bbolin": "lin", - "cap": ["cap", "pcap"], - "cu-seeme": "cu", - "davmount+xml": "davmount", - "dsptype": "tsp", - "ecmascript": ["es", "ecma"], - "futuresplash": "spl", - "hta": "hta", - "java-archive": "jar", - "java-serialized-object": "ser", - "java-vm": "class", - "javascript": "js", - "m3g": "m3g", - "mac-binhex40": "hqx", - "mathematica": ["nb", "ma", "mb"], - "msaccess": "mdb", - "msword": ["doc", "dot"], - "mxf": "mxf", - "oda": "oda", - "ogg": "ogx", - "pdf": "pdf", - "pgp-keys": "key", - "pgp-signature": ["asc", "sig"], - "pics-rules": "prf", - "postscript": ["ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3"], - "rar": "rar", - "rdf+xml": "rdf", - "rss+xml": "rss", - "rtf": "rtf", - "smil": ["smi", "smil"], - "xhtml+xml": ["xhtml", "xht"], - "xml": ["xml", "xsl", "xsd"], - "xspf+xml": "xspf", - "zip": "zip", - "vnd.android.package-archive": "apk", - "vnd.cinderella": "cdy", - "vnd.google-earth.kml+xml": "kml", - "vnd.google-earth.kmz": "kmz", - "vnd.mozilla.xul+xml": "xul", - "vnd.ms-excel": ["xls", "xlb", "xlt", "xlm", "xla", "xlc", "xlw"], - "vnd.ms-pki.seccat": "cat", - "vnd.ms-pki.stl": "stl", - "vnd.ms-powerpoint": ["ppt", "pps", "pot"], - "vnd.oasis.opendocument.chart": "odc", - "vnd.oasis.opendocument.database": "odb", - "vnd.oasis.opendocument.formula": "odf", - "vnd.oasis.opendocument.graphics": "odg", - "vnd.oasis.opendocument.graphics-template": "otg", - "vnd.oasis.opendocument.image": "odi", - "vnd.oasis.opendocument.presentation": "odp", - "vnd.oasis.opendocument.presentation-template": "otp", - "vnd.oasis.opendocument.spreadsheet": "ods", - "vnd.oasis.opendocument.spreadsheet-template": "ots", - "vnd.oasis.opendocument.text": "odt", - "vnd.oasis.opendocument.text-master": "odm", - "vnd.oasis.opendocument.text-template": "ott", - "vnd.oasis.opendocument.text-web": "oth", - "vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx", - "vnd.openxmlformats-officedocument.spreadsheetml.template": "xltx", - "vnd.openxmlformats-officedocument.presentationml.presentation": "pptx", - "vnd.openxmlformats-officedocument.presentationml.slideshow": "ppsx", - "vnd.openxmlformats-officedocument.presentationml.template": "potx", - "vnd.openxmlformats-officedocument.wordprocessingml.document": "docx", - "vnd.openxmlformats-officedocument.wordprocessingml.template": "dotx", - "vnd.smaf": "mmf", - "vnd.stardivision.calc": "sdc", - "vnd.stardivision.chart": "sds", - "vnd.stardivision.draw": "sda", - "vnd.stardivision.impress": "sdd", - "vnd.stardivision.math": ["sdf", "smf"], - "vnd.stardivision.writer": ["sdw", "vor"], - "vnd.stardivision.writer-global": "sgl", - "vnd.sun.xml.calc": "sxc", - "vnd.sun.xml.calc.template": "stc", - "vnd.sun.xml.draw": "sxd", - "vnd.sun.xml.draw.template": "std", - "vnd.sun.xml.impress": "sxi", - "vnd.sun.xml.impress.template": "sti", - "vnd.sun.xml.math": "sxm", - "vnd.sun.xml.writer": "sxw", - "vnd.sun.xml.writer.global": "sxg", - "vnd.sun.xml.writer.template": "stw", - "vnd.symbian.install": ["sis", "sisx"], - "vnd.visio": ["vsd", "vst", "vss", "vsw"], - "vnd.wap.wbxml": "wbxml", - "vnd.wap.wmlc": "wmlc", - "vnd.wap.wmlscriptc": "wmlsc", - "vnd.wordperfect": "wpd", - "vnd.wordperfect5.1": "wp5", - "x-123": "wk", - "x-7z-compressed": "7z", - "x-abiword": "abw", - "x-apple-diskimage": "dmg", - "x-bcpio": "bcpio", - "x-bittorrent": "torrent", - "x-cbr": ["cbr", "cba", "cbt", "cb7"], - "x-cbz": "cbz", - "x-cdf": ["cdf", "cda"], - "x-cdlink": "vcd", - "x-chess-pgn": "pgn", - "x-cpio": "cpio", - "x-csh": "csh", - "x-debian-package": ["deb", "udeb"], - "x-director": ["dcr", "dir", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa"], - "x-dms": "dms", - "x-doom": "wad", - "x-dvi": "dvi", - "x-httpd-eruby": "rhtml", - "x-font": "pcf.Z", - "x-freemind": "mm", - "x-gnumeric": "gnumeric", - "x-go-sgf": "sgf", - "x-graphing-calculator": "gcf", - "x-gtar": ["gtar", "taz"], - "x-hdf": "hdf", - "x-httpd-php": ["phtml", "pht", "php"], - "x-httpd-php-source": "phps", - "x-httpd-php3": "php3", - "x-httpd-php3-preprocessed": "php3p", - "x-httpd-php4": "php4", - "x-httpd-php5": "php5", - "x-ica": "ica", - "x-info": "info", - "x-internet-signup": ["ins", "isp"], - "x-iphone": "iii", - "x-iso9660-image": "iso", - "x-java-jnlp-file": "jnlp", - "x-jmol": "jmz", - "x-killustrator": "kil", - "x-koan": ["skp", "skd", "skt", "skm"], - "x-kpresenter": ["kpr", "kpt"], - "x-kword": ["kwd", "kwt"], - "x-latex": "latex", - "x-lha": "lha", - "x-lyx": "lyx", - "x-lzh": "lzh", - "x-lzx": "lzx", - "x-maker": ["frm", "maker", "frame", "fm", "fb", "book", "fbdoc"], - "x-ms-wmd": "wmd", - "x-ms-wmz": "wmz", - "x-msdos-program": ["com", "exe", "bat", "dll"], - "x-msi": "msi", - "x-netcdf": ["nc", "cdf"], - "x-ns-proxy-autoconfig": ["pac", "dat"], - "x-nwc": "nwc", - "x-object": "o", - "x-oz-application": "oza", - "x-pkcs7-certreqresp": "p7r", - "x-python-code": ["pyc", "pyo"], - "x-qgis": ["qgs", "shp", "shx"], - "x-quicktimeplayer": "qtl", - "x-redhat-package-manager": "rpm", - "x-ruby": "rb", - "x-sh": "sh", - "x-shar": "shar", - "x-shockwave-flash": ["swf", "swfl"], - "x-silverlight": "scr", - "x-stuffit": "sit", - "x-sv4cpio": "sv4cpio", - "x-sv4crc": "sv4crc", - "x-tar": "tar", - "x-tcl": "tcl", - "x-tex-gf": "gf", - "x-tex-pk": "pk", - "x-texinfo": ["texinfo", "texi"], - "x-trash": ["~", "%", "bak", "old", "sik"], - "x-troff": ["t", "tr", "roff"], - "x-troff-man": "man", - "x-troff-me": "me", - "x-troff-ms": "ms", - "x-ustar": "ustar", - "x-wais-source": "src", - "x-wingz": "wz", - "x-x509-ca-cert": ["crt", "der", "cer"], - "x-xcf": "xcf", - "x-xfig": "fig", - "x-xpinstall": "xpi", - "applixware": "aw", - "atomsvc+xml": "atomsvc", - "ccxml+xml": "ccxml", - "cdmi-capability": "cdmia", - "cdmi-container": "cdmic", - "cdmi-domain": "cdmid", - "cdmi-object": "cdmio", - "cdmi-queue": "cdmiq", - "docbook+xml": "dbk", - "dssc+der": "dssc", - "dssc+xml": "xdssc", - "emma+xml": "emma", - "epub+zip": "epub", - "exi": "exi", - "font-tdpfr": "pfr", - "gml+xml": "gml", - "gpx+xml": "gpx", - "gxf": "gxf", - "hyperstudio": "stk", - "inkml+xml": ["ink", "inkml"], - "ipfix": "ipfix", - "json": "json", - "jsonml+json": "jsonml", - "lost+xml": "lostxml", - "mads+xml": "mads", - "marc": "mrc", - "marcxml+xml": "mrcx", - "mathml+xml": "mathml", - "mbox": "mbox", - "mediaservercontrol+xml": "mscml", - "metalink+xml": "metalink", - "metalink4+xml": "meta4", - "mets+xml": "mets", - "mods+xml": "mods", - "mp21": ["m21", "mp21"], - "mp4": "mp4s", - "oebps-package+xml": "opf", - "omdoc+xml": "omdoc", - "onenote": ["onetoc", "onetoc2", "onetmp", "onepkg"], - "oxps": "oxps", - "patch-ops-error+xml": "xer", - "pgp-encrypted": "pgp", - "pkcs10": "p10", - "pkcs7-mime": ["p7m", "p7c"], - "pkcs7-signature": "p7s", - "pkcs8": "p8", - "pkix-attr-cert": "ac", - "pkix-crl": "crl", - "pkix-pkipath": "pkipath", - "pkixcmp": "pki", - "pls+xml": "pls", - "prs.cww": "cww", - "pskc+xml": "pskcxml", - "reginfo+xml": "rif", - "relax-ng-compact-syntax": "rnc", - "resource-lists+xml": "rl", - "resource-lists-diff+xml": "rld", - "rls-services+xml": "rs", - "rpki-ghostbusters": "gbr", - "rpki-manifest": "mft", - "rpki-roa": "roa", - "rsd+xml": "rsd", - "sbml+xml": "sbml", - "scvp-cv-request": "scq", - "scvp-cv-response": "scs", - "scvp-vp-request": "spq", - "scvp-vp-response": "spp", - "sdp": "sdp", - "set-payment-initiation": "setpay", - "set-registration-initiation": "setreg", - "shf+xml": "shf", - "sparql-query": "rq", - "sparql-results+xml": "srx", - "srgs": "gram", - "srgs+xml": "grxml", - "sru+xml": "sru", - "ssdl+xml": "ssdl", - "ssml+xml": "ssml", - "tei+xml": ["tei", "teicorpus"], - "thraud+xml": "tfi", - "timestamped-data": "tsd", - "vnd.3gpp.pic-bw-large": "plb", - "vnd.3gpp.pic-bw-small": "psb", - "vnd.3gpp.pic-bw-var": "pvb", - "vnd.3gpp2.tcap": "tcap", - "vnd.3m.post-it-notes": "pwn", - "vnd.accpac.simply.aso": "aso", - "vnd.accpac.simply.imp": "imp", - "vnd.acucobol": "acu", - "vnd.acucorp": ["atc", "acutc"], - "vnd.adobe.air-application-installer-package+zip": "air", - "vnd.adobe.formscentral.fcdt": "fcdt", - "vnd.adobe.fxp": ["fxp", "fxpl"], - "vnd.adobe.xdp+xml": "xdp", - "vnd.adobe.xfdf": "xfdf", - "vnd.ahead.space": "ahead", - "vnd.airzip.filesecure.azf": "azf", - "vnd.airzip.filesecure.azs": "azs", - "vnd.amazon.ebook": "azw", - "vnd.americandynamics.acc": "acc", - "vnd.amiga.ami": "ami", - "vnd.anser-web-certificate-issue-initiation": "cii", - "vnd.anser-web-funds-transfer-initiation": "fti", - "vnd.antix.game-component": "atx", - "vnd.apple.installer+xml": "mpkg", - "vnd.apple.mpegurl": "m3u8", - "vnd.aristanetworks.swi": "swi", - "vnd.astraea-software.iota": "iota", - "vnd.audiograph": "aep", - "vnd.blueice.multipass": "mpm", - "vnd.bmi": "bmi", - "vnd.businessobjects": "rep", - "vnd.chemdraw+xml": "cdxml", - "vnd.chipnuts.karaoke-mmd": "mmd", - "vnd.claymore": "cla", - "vnd.cloanto.rp9": "rp9", - "vnd.clonk.c4group": ["c4g", "c4d", "c4f", "c4p", "c4u"], - "vnd.cluetrust.cartomobile-config": "c11amc", - "vnd.cluetrust.cartomobile-config-pkg": "c11amz", - "vnd.commonspace": "csp", - "vnd.contact.cmsg": "cdbcmsg", - "vnd.cosmocaller": "cmc", - "vnd.crick.clicker": "clkx", - "vnd.crick.clicker.keyboard": "clkk", - "vnd.crick.clicker.palette": "clkp", - "vnd.crick.clicker.template": "clkt", - "vnd.crick.clicker.wordbank": "clkw", - "vnd.criticaltools.wbs+xml": "wbs", - "vnd.ctc-posml": "pml", - "vnd.cups-ppd": "ppd", - "vnd.curl.car": "car", - "vnd.curl.pcurl": "pcurl", - "vnd.dart": "dart", - "vnd.data-vision.rdz": "rdz", - "vnd.dece.data": ["uvf", "uvvf", "uvd", "uvvd"], - "vnd.dece.ttml+xml": ["uvt", "uvvt"], - "vnd.dece.unspecified": ["uvx", "uvvx"], - "vnd.dece.zip": ["uvz", "uvvz"], - "vnd.denovo.fcselayout-link": "fe_launch", - "vnd.dna": "dna", - "vnd.dolby.mlp": "mlp", - "vnd.dpgraph": "dpg", - "vnd.dreamfactory": "dfac", - "vnd.ds-keypoint": "kpxx", - "vnd.dvb.ait": "ait", - "vnd.dvb.service": "svc", - "vnd.dynageo": "geo", - "vnd.ecowin.chart": "mag", - "vnd.enliven": "nml", - "vnd.epson.esf": "esf", - "vnd.epson.msf": "msf", - "vnd.epson.quickanime": "qam", - "vnd.epson.salt": "slt", - "vnd.epson.ssf": "ssf", - "vnd.eszigno3+xml": ["es3", "et3"], - "vnd.ezpix-album": "ez2", - "vnd.ezpix-package": "ez3", - "vnd.fdf": "fdf", - "vnd.fdsn.mseed": "mseed", - "vnd.fdsn.seed": ["seed", "dataless"], - "vnd.flographit": "gph", - "vnd.fluxtime.clip": "ftc", - "vnd.framemaker": ["fm", "frame", "maker", "book"], - "vnd.frogans.fnc": "fnc", - "vnd.frogans.ltf": "ltf", - "vnd.fsc.weblaunch": "fsc", - "vnd.fujitsu.oasys": "oas", - "vnd.fujitsu.oasys2": "oa2", - "vnd.fujitsu.oasys3": "oa3", - "vnd.fujitsu.oasysgp": "fg5", - "vnd.fujitsu.oasysprs": "bh2", - "vnd.fujixerox.ddd": "ddd", - "vnd.fujixerox.docuworks": "xdw", - "vnd.fujixerox.docuworks.binder": "xbd", - "vnd.fuzzysheet": "fzs", - "vnd.genomatix.tuxedo": "txd", - "vnd.geogebra.file": "ggb", - "vnd.geogebra.tool": "ggt", - "vnd.geometry-explorer": ["gex", "gre"], - "vnd.geonext": "gxt", - "vnd.geoplan": "g2w", - "vnd.geospace": "g3w", - "vnd.gmx": "gmx", - "vnd.grafeq": ["gqf", "gqs"], - "vnd.groove-account": "gac", - "vnd.groove-help": "ghf", - "vnd.groove-identity-message": "gim", - "vnd.groove-injector": "grv", - "vnd.groove-tool-message": "gtm", - "vnd.groove-tool-template": "tpl", - "vnd.groove-vcard": "vcg", - "vnd.hal+xml": "hal", - "vnd.handheld-entertainment+xml": "zmm", - "vnd.hbci": "hbci", - "vnd.hhe.lesson-player": "les", - "vnd.hp-hpgl": "hpgl", - "vnd.hp-hpid": "hpid", - "vnd.hp-hps": "hps", - "vnd.hp-jlyt": "jlt", - "vnd.hp-pcl": "pcl", - "vnd.hp-pclxl": "pclxl", - "vnd.hydrostatix.sof-data": "sfd-hdstx", - "vnd.ibm.minipay": "mpy", - "vnd.ibm.modcap": ["afp", "listafp", "list3820"], - "vnd.ibm.rights-management": "irm", - "vnd.ibm.secure-container": "sc", - "vnd.iccprofile": ["icc", "icm"], - "vnd.igloader": "igl", - "vnd.immervision-ivp": "ivp", - "vnd.immervision-ivu": "ivu", - "vnd.insors.igm": "igm", - "vnd.intercon.formnet": ["xpw", "xpx"], - "vnd.intergeo": "i2g", - "vnd.intu.qbo": "qbo", - "vnd.intu.qfx": "qfx", - "vnd.ipunplugged.rcprofile": "rcprofile", - "vnd.irepository.package+xml": "irp", - "vnd.is-xpr": "xpr", - "vnd.isac.fcs": "fcs", - "vnd.jam": "jam", - "vnd.jcp.javame.midlet-rms": "rms", - "vnd.jisp": "jisp", - "vnd.joost.joda-archive": "joda", - "vnd.kahootz": ["ktz", "ktr"], - "vnd.kde.karbon": "karbon", - "vnd.kde.kchart": "chrt", - "vnd.kde.kformula": "kfo", - "vnd.kde.kivio": "flw", - "vnd.kde.kontour": "kon", - "vnd.kde.kpresenter": ["kpr", "kpt"], - "vnd.kde.kspread": "ksp", - "vnd.kde.kword": ["kwd", "kwt"], - "vnd.kenameaapp": "htke", - "vnd.kidspiration": "kia", - "vnd.kinar": ["kne", "knp"], - "vnd.koan": ["skp", "skd", "skt", "skm"], - "vnd.kodak-descriptor": "sse", - "vnd.las.las+xml": "lasxml", - "vnd.llamagraphics.life-balance.desktop": "lbd", - "vnd.llamagraphics.life-balance.exchange+xml": "lbe", - "vnd.lotus-1-2-3": "123", - "vnd.lotus-approach": "apr", - "vnd.lotus-freelance": "pre", - "vnd.lotus-notes": "nsf", - "vnd.lotus-organizer": "org", - "vnd.lotus-screencam": "scm", - "vnd.lotus-wordpro": "lwp", - "vnd.macports.portpkg": "portpkg", - "vnd.mcd": "mcd", - "vnd.medcalcdata": "mc1", - "vnd.mediastation.cdkey": "cdkey", - "vnd.mfer": "mwf", - "vnd.mfmp": "mfm", - "vnd.micrografx.flo": "flo", - "vnd.micrografx.igx": "igx", - "vnd.mif": "mif", - "vnd.mobius.daf": "daf", - "vnd.mobius.dis": "dis", - "vnd.mobius.mbk": "mbk", - "vnd.mobius.mqy": "mqy", - "vnd.mobius.msl": "msl", - "vnd.mobius.plc": "plc", - "vnd.mobius.txf": "txf", - "vnd.mophun.application": "mpn", - "vnd.mophun.certificate": "mpc", - "vnd.ms-artgalry": "cil", - "vnd.ms-cab-compressed": "cab", - "vnd.ms-excel.addin.macroenabled.12": "xlam", - "vnd.ms-excel.sheet.binary.macroenabled.12": "xlsb", - "vnd.ms-excel.sheet.macroenabled.12": "xlsm", - "vnd.ms-excel.template.macroenabled.12": "xltm", - "vnd.ms-fontobject": "eot", - "vnd.ms-htmlhelp": "chm", - "vnd.ms-ims": "ims", - "vnd.ms-lrm": "lrm", - "vnd.ms-officetheme": "thmx", - "vnd.ms-powerpoint.addin.macroenabled.12": "ppam", - "vnd.ms-powerpoint.presentation.macroenabled.12": "pptm", - "vnd.ms-powerpoint.slide.macroenabled.12": "sldm", - "vnd.ms-powerpoint.slideshow.macroenabled.12": "ppsm", - "vnd.ms-powerpoint.template.macroenabled.12": "potm", - "vnd.ms-project": ["mpp", "mpt"], - "vnd.ms-word.document.macroenabled.12": "docm", - "vnd.ms-word.template.macroenabled.12": "dotm", - "vnd.ms-works": ["wps", "wks", "wcm", "wdb"], - "vnd.ms-wpl": "wpl", - "vnd.ms-xpsdocument": "xps", - "vnd.mseq": "mseq", - "vnd.musician": "mus", - "vnd.muvee.style": "msty", - "vnd.mynfc": "taglet", - "vnd.neurolanguage.nlu": "nlu", - "vnd.nitf": ["ntf", "nitf"], - "vnd.noblenet-directory": "nnd", - "vnd.noblenet-sealer": "nns", - "vnd.noblenet-web": "nnw", - "vnd.nokia.n-gage.data": "ngdat", - "vnd.nokia.n-gage.symbian.install": "n-gage", - "vnd.nokia.radio-preset": "rpst", - "vnd.nokia.radio-presets": "rpss", - "vnd.novadigm.edm": "edm", - "vnd.novadigm.edx": "edx", - "vnd.novadigm.ext": "ext", - "vnd.oasis.opendocument.chart-template": "otc", - "vnd.oasis.opendocument.formula-template": "odft", - "vnd.oasis.opendocument.image-template": "oti", - "vnd.olpc-sugar": "xo", - "vnd.oma.dd2+xml": "dd2", - "vnd.openofficeorg.extension": "oxt", - "vnd.openxmlformats-officedocument.presentationml.slide": "sldx", - "vnd.osgeo.mapguide.package": "mgp", - "vnd.osgi.dp": "dp", - "vnd.osgi.subsystem": "esa", - "vnd.palm": ["pdb", "pqa", "oprc"], - "vnd.pawaafile": "paw", - "vnd.pg.format": "str", - "vnd.pg.osasli": "ei6", - "vnd.picsel": "efif", - "vnd.pmi.widget": "wg", - "vnd.pocketlearn": "plf", - "vnd.powerbuilder6": "pbd", - "vnd.previewsystems.box": "box", - "vnd.proteus.magazine": "mgz", - "vnd.publishare-delta-tree": "qps", - "vnd.pvi.ptid1": "ptid", - "vnd.quark.quarkxpress": ["qxd", "qxt", "qwd", "qwt", "qxl", "qxb"], - "vnd.realvnc.bed": "bed", - "vnd.recordare.musicxml": "mxl", - "vnd.recordare.musicxml+xml": "musicxml", - "vnd.rig.cryptonote": "cryptonote", - "vnd.rn-realmedia": "rm", - "vnd.rn-realmedia-vbr": "rmvb", - "vnd.route66.link66+xml": "link66", - "vnd.sailingtracker.track": "st", - "vnd.seemail": "see", - "vnd.sema": "sema", - "vnd.semd": "semd", - "vnd.semf": "semf", - "vnd.shana.informed.formdata": "ifm", - "vnd.shana.informed.formtemplate": "itp", - "vnd.shana.informed.interchange": "iif", - "vnd.shana.informed.package": "ipk", - "vnd.simtech-mindmapper": ["twd", "twds"], - "vnd.smart.teacher": "teacher", - "vnd.solent.sdkm+xml": ["sdkm", "sdkd"], - "vnd.spotfire.dxp": "dxp", - "vnd.spotfire.sfs": "sfs", - "vnd.stepmania.package": "smzip", - "vnd.stepmania.stepchart": "sm", - "vnd.sus-calendar": ["sus", "susp"], - "vnd.svd": "svd", - "vnd.syncml+xml": "xsm", - "vnd.syncml.dm+wbxml": "bdm", - "vnd.syncml.dm+xml": "xdm", - "vnd.tao.intent-module-archive": "tao", - "vnd.tcpdump.pcap": ["pcap", "cap", "dmp"], - "vnd.tmobile-livetv": "tmo", - "vnd.trid.tpt": "tpt", - "vnd.triscape.mxs": "mxs", - "vnd.trueapp": "tra", - "vnd.ufdl": ["ufd", "ufdl"], - "vnd.uiq.theme": "utz", - "vnd.umajin": "umj", - "vnd.unity": "unityweb", - "vnd.uoml+xml": "uoml", - "vnd.vcx": "vcx", - "vnd.visionary": "vis", - "vnd.vsf": "vsf", - "vnd.webturbo": "wtb", - "vnd.wolfram.player": "nbp", - "vnd.wqd": "wqd", - "vnd.wt.stf": "stf", - "vnd.xara": "xar", - "vnd.xfdl": "xfdl", - "vnd.yamaha.hv-dic": "hvd", - "vnd.yamaha.hv-script": "hvs", - "vnd.yamaha.hv-voice": "hvp", - "vnd.yamaha.openscoreformat": "osf", - "vnd.yamaha.openscoreformat.osfpvg+xml": "osfpvg", - "vnd.yamaha.smaf-audio": "saf", - "vnd.yamaha.smaf-phrase": "spf", - "vnd.yellowriver-custom-menu": "cmp", - "vnd.zul": ["zir", "zirz"], - "vnd.zzazz.deck+xml": "zaz", - "voicexml+xml": "vxml", - "widget": "wgt", - "winhlp": "hlp", - "wsdl+xml": "wsdl", - "wspolicy+xml": "wspolicy", - "x-ace-compressed": "ace", - "x-authorware-bin": ["aab", "x32", "u32", "vox"], - "x-authorware-map": "aam", - "x-authorware-seg": "aas", - "x-blorb": ["blb", "blorb"], - "x-bzip": "bz", - "x-bzip2": ["bz2", "boz"], - "x-cfs-compressed": "cfs", - "x-chat": "chat", - "x-conference": "nsc", - "x-dgc-compressed": "dgc", - "x-dtbncx+xml": "ncx", - "x-dtbook+xml": "dtb", - "x-dtbresource+xml": "res", - "x-eva": "eva", - "x-font-bdf": "bdf", - "x-font-ghostscript": "gsf", - "x-font-linux-psf": "psf", - "x-font-otf": "otf", - "x-font-pcf": "pcf", - "x-font-snf": "snf", - "x-font-ttf": ["ttf", "ttc"], - "x-font-type1": ["pfa", "pfb", "pfm", "afm"], - "x-font-woff": "woff", - "x-freearc": "arc", - "x-gca-compressed": "gca", - "x-glulx": "ulx", - "x-gramps-xml": "gramps", - "x-install-instructions": "install", - "x-lzh-compressed": ["lzh", "lha"], - "x-mie": "mie", - "x-mobipocket-ebook": ["prc", "mobi"], - "x-ms-application": "application", - "x-ms-shortcut": "lnk", - "x-ms-xbap": "xbap", - "x-msbinder": "obd", - "x-mscardfile": "crd", - "x-msclip": "clp", - "x-msdownload": ["exe", "dll", "com", "bat", "msi"], - "x-msmediaview": ["mvb", "m13", "m14"], - "x-msmetafile": ["wmf", "wmz", "emf", "emz"], - "x-msmoney": "mny", - "x-mspublisher": "pub", - "x-msschedule": "scd", - "x-msterminal": "trm", - "x-mswrite": "wri", - "x-nzb": "nzb", - "x-pkcs12": ["p12", "pfx"], - "x-pkcs7-certificates": ["p7b", "spc"], - "x-research-info-systems": "ris", - "x-silverlight-app": "xap", - "x-sql": "sql", - "x-stuffitx": "sitx", - "x-subrip": "srt", - "x-t3vm-image": "t3", - "x-tads": "gam", - "x-tex": "tex", - "x-tex-tfm": "tfm", - "x-tgif": "obj", - "x-xliff+xml": "xlf", - "x-xz": "xz", - "x-zmachine": ["z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8"], - "xaml+xml": "xaml", - "xcap-diff+xml": "xdf", - "xenc+xml": "xenc", - "xml-dtd": "dtd", - "xop+xml": "xop", - "xproc+xml": "xpl", - "xslt+xml": "xslt", - "xv+xml": ["mxml", "xhvml", "xvml", "xvm"], - "yang": "yang", - "yin+xml": "yin", - "envoy": "evy", - "fractals": "fif", - "internet-property-stream": "acx", - "olescript": "axs", - "vnd.ms-outlook": "msg", - "vnd.ms-pkicertstore": "sst", - "x-compress": "z", - "x-compressed": "tgz", - "x-gzip": "gz", - "x-perfmon": ["pma", "pmc", "pml", "pmr", "pmw"], - "x-pkcs7-mime": ["p7c", "p7m"], - "ynd.ms-pkipko": "pko" - }, - "audio": { - "amr": "amr", - "amr-wb": "awb", - "annodex": "axa", - "basic": ["au", "snd"], - "flac": "flac", - "midi": ["mid", "midi", "kar", "rmi"], - "mpeg": ["mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a"], - "mpegurl": "m3u", - "ogg": ["oga", "ogg", "spx"], - "prs.sid": "sid", - "x-aiff": ["aif", "aiff", "aifc"], - "x-gsm": "gsm", - "x-ms-wma": "wma", - "x-ms-wax": "wax", - "x-pn-realaudio": "ram", - "x-realaudio": "ra", - "x-sd2": "sd2", - "x-wav": "wav", - "adpcm": "adp", - "mp4": "mp4a", - "s3m": "s3m", - "silk": "sil", - "vnd.dece.audio": ["uva", "uvva"], - "vnd.digital-winds": "eol", - "vnd.dra": "dra", - "vnd.dts": "dts", - "vnd.dts.hd": "dtshd", - "vnd.lucent.voice": "lvp", - "vnd.ms-playready.media.pya": "pya", - "vnd.nuera.ecelp4800": "ecelp4800", - "vnd.nuera.ecelp7470": "ecelp7470", - "vnd.nuera.ecelp9600": "ecelp9600", - "vnd.rip": "rip", - "webm": "weba", - "x-aac": "aac", - "x-caf": "caf", - "x-matroska": "mka", - "x-pn-realaudio-plugin": "rmp", - "xm": "xm", - "mid": ["mid", "rmi"] - }, - "chemical": { - "x-alchemy": "alc", - "x-cache": ["cac", "cache"], - "x-cache-csf": "csf", - "x-cactvs-binary": ["cbin", "cascii", "ctab"], - "x-cdx": "cdx", - "x-chem3d": "c3d", - "x-cif": "cif", - "x-cmdf": "cmdf", - "x-cml": "cml", - "x-compass": "cpa", - "x-crossfire": "bsd", - "x-csml": ["csml", "csm"], - "x-ctx": "ctx", - "x-cxf": ["cxf", "cef"], - "x-embl-dl-nucleotide": ["emb", "embl"], - "x-gamess-input": ["inp", "gam", "gamin"], - "x-gaussian-checkpoint": ["fch", "fchk"], - "x-gaussian-cube": "cub", - "x-gaussian-input": ["gau", "gjc", "gjf"], - "x-gaussian-log": "gal", - "x-gcg8-sequence": "gcg", - "x-genbank": "gen", - "x-hin": "hin", - "x-isostar": ["istr", "ist"], - "x-jcamp-dx": ["jdx", "dx"], - "x-kinemage": "kin", - "x-macmolecule": "mcm", - "x-macromodel-input": ["mmd", "mmod"], - "x-mdl-molfile": "mol", - "x-mdl-rdfile": "rd", - "x-mdl-rxnfile": "rxn", - "x-mdl-sdfile": ["sd", "sdf"], - "x-mdl-tgf": "tgf", - "x-mmcif": "mcif", - "x-mol2": "mol2", - "x-molconn-Z": "b", - "x-mopac-graph": "gpt", - "x-mopac-input": ["mop", "mopcrt", "mpc", "zmt"], - "x-mopac-out": "moo", - "x-ncbi-asn1": "asn", - "x-ncbi-asn1-ascii": ["prt", "ent"], - "x-ncbi-asn1-binary": ["val", "aso"], - "x-pdb": ["pdb", "ent"], - "x-rosdal": "ros", - "x-swissprot": "sw", - "x-vamas-iso14976": "vms", - "x-vmd": "vmd", - "x-xtel": "xtel", - "x-xyz": "xyz" - }, - "image": { - "gif": "gif", - "ief": "ief", - "jpeg": ["jpeg", "jpg", "jpe"], - "pcx": "pcx", - "png": "png", - "svg+xml": ["svg", "svgz"], - "tiff": ["tiff", "tif"], - "vnd.djvu": ["djvu", "djv"], - "vnd.wap.wbmp": "wbmp", - "x-canon-cr2": "cr2", - "x-canon-crw": "crw", - "x-cmu-raster": "ras", - "x-coreldraw": "cdr", - "x-coreldrawpattern": "pat", - "x-coreldrawtemplate": "cdt", - "x-corelphotopaint": "cpt", - "x-epson-erf": "erf", - "x-icon": "ico", - "x-jg": "art", - "x-jng": "jng", - "x-nikon-nef": "nef", - "x-olympus-orf": "orf", - "x-photoshop": "psd", - "x-portable-anymap": "pnm", - "x-portable-bitmap": "pbm", - "x-portable-graymap": "pgm", - "x-portable-pixmap": "ppm", - "x-rgb": "rgb", - "x-xbitmap": "xbm", - "x-xpixmap": "xpm", - "x-xwindowdump": "xwd", - "bmp": "bmp", - "cgm": "cgm", - "g3fax": "g3", - "ktx": "ktx", - "prs.btif": "btif", - "sgi": "sgi", - "vnd.dece.graphic": ["uvi", "uvvi", "uvg", "uvvg"], - "vnd.dwg": "dwg", - "vnd.dxf": "dxf", - "vnd.fastbidsheet": "fbs", - "vnd.fpx": "fpx", - "vnd.fst": "fst", - "vnd.fujixerox.edmics-mmr": "mmr", - "vnd.fujixerox.edmics-rlc": "rlc", - "vnd.ms-modi": "mdi", - "vnd.ms-photo": "wdp", - "vnd.net-fpx": "npx", - "vnd.xiff": "xif", - "webp": "webp", - "x-3ds": "3ds", - "x-cmx": "cmx", - "x-freehand": ["fh", "fhc", "fh4", "fh5", "fh7"], - "x-pict": ["pic", "pct"], - "x-tga": "tga", - "cis-cod": "cod", - "pipeg": "jfif" - }, - "message": { - "rfc822": ["eml", "mime", "mht", "mhtml", "nws"] - }, - "model": { - "iges": ["igs", "iges"], - "mesh": ["msh", "mesh", "silo"], - "vrml": ["wrl", "vrml"], - "x3d+vrml": ["x3dv", "x3dvz"], - "x3d+xml": ["x3d", "x3dz"], - "x3d+binary": ["x3db", "x3dbz"], - "vnd.collada+xml": "dae", - "vnd.dwf": "dwf", - "vnd.gdl": "gdl", - "vnd.gtw": "gtw", - "vnd.mts": "mts", - "vnd.vtu": "vtu" - }, - "text": { - "cache-manifest": ["manifest", "appcache"], - "calendar": ["ics", "icz", "ifb"], - "css": "css", - "csv": "csv", - "h323": "323", - "html": ["html", "htm", "shtml", "stm"], - "iuls": "uls", - "mathml": "mml", - "plain": ["txt", "text", "brf", "conf", "def", "list", "log", "in", "bas"], - "richtext": "rtx", - "scriptlet": ["sct", "wsc"], - "texmacs": ["tm", "ts"], - "tab-separated-values": "tsv", - "vnd.sun.j2me.app-descriptor": "jad", - "vnd.wap.wml": "wml", - "vnd.wap.wmlscript": "wmls", - "x-bibtex": "bib", - "x-boo": "boo", - "x-c++hdr": ["h++", "hpp", "hxx", "hh"], - "x-c++src": ["c++", "cpp", "cxx", "cc"], - "x-component": "htc", - "x-dsrc": "d", - "x-diff": ["diff", "patch"], - "x-haskell": "hs", - "x-java": "java", - "x-literate-haskell": "lhs", - "x-moc": "moc", - "x-pascal": ["p", "pas"], - "x-pcs-gcd": "gcd", - "x-perl": ["pl", "pm"], - "x-python": "py", - "x-scala": "scala", - "x-setext": "etx", - "x-tcl": ["tcl", "tk"], - "x-tex": ["tex", "ltx", "sty", "cls"], - "x-vcalendar": "vcs", - "x-vcard": "vcf", - "n3": "n3", - "prs.lines.tag": "dsc", - "sgml": ["sgml", "sgm"], - "troff": ["t", "tr", "roff", "man", "me", "ms"], - "turtle": "ttl", - "uri-list": ["uri", "uris", "urls"], - "vcard": "vcard", - "vnd.curl": "curl", - "vnd.curl.dcurl": "dcurl", - "vnd.curl.scurl": "scurl", - "vnd.curl.mcurl": "mcurl", - "vnd.dvb.subtitle": "sub", - "vnd.fly": "fly", - "vnd.fmi.flexstor": "flx", - "vnd.graphviz": "gv", - "vnd.in3d.3dml": "3dml", - "vnd.in3d.spot": "spot", - "x-asm": ["s", "asm"], - "x-c": ["c", "cc", "cxx", "cpp", "h", "hh", "dic"], - "x-fortran": ["f", "for", "f77", "f90"], - "x-opml": "opml", - "x-nfo": "nfo", - "x-sfv": "sfv", - "x-uuencode": "uu", - "webviewhtml": "htt" - }, - "video": { - "avif": ".avif", - "3gpp": "3gp", - "annodex": "axv", - "dl": "dl", - "dv": ["dif", "dv"], - "fli": "fli", - "gl": "gl", - "mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2"], - "mp4": ["mp4", "mp4v", "mpg4"], - "quicktime": ["qt", "mov"], - "ogg": "ogv", - "vnd.mpegurl": ["mxu", "m4u"], - "x-flv": "flv", - "x-la-asf": ["lsf", "lsx"], - "x-mng": "mng", - "x-ms-asf": ["asf", "asx", "asr"], - "x-ms-wm": "wm", - "x-ms-wmv": "wmv", - "x-ms-wmx": "wmx", - "x-ms-wvx": "wvx", - "x-msvideo": "avi", - "x-sgi-movie": "movie", - "x-matroska": ["mpv", "mkv", "mk3d", "mks"], - "3gpp2": "3g2", - "h261": "h261", - "h263": "h263", - "h264": "h264", - "jpeg": "jpgv", - "jpm": ["jpm", "jpgm"], - "mj2": ["mj2", "mjp2"], - "vnd.dece.hd": ["uvh", "uvvh"], - "vnd.dece.mobile": ["uvm", "uvvm"], - "vnd.dece.pd": ["uvp", "uvvp"], - "vnd.dece.sd": ["uvs", "uvvs"], - "vnd.dece.video": ["uvv", "uvvv"], - "vnd.dvb.file": "dvb", - "vnd.fvt": "fvt", - "vnd.ms-playready.media.pyv": "pyv", - "vnd.uvvu.mp4": ["uvu", "uvvu"], - "vnd.vivo": "viv", - "webm": "webm", - "x-f4v": "f4v", - "x-m4v": "m4v", - "x-ms-vob": "vob", - "x-smv": "smv" - }, - "x-conference": { - "x-cooltalk": "ice" - }, - "x-world": { - "x-vrml": ["vrm", "vrml", "wrl", "flr", "wrz", "xaf", "xof"] - } -}; - -(() => { - const mimeTypes = {}; - for (const type in table$1) { - // eslint-disable-next-line no-prototype-builtins - if (table$1.hasOwnProperty(type)) { - for (const subtype in table$1[type]) { - // eslint-disable-next-line no-prototype-builtins - if (table$1[type].hasOwnProperty(subtype)) { - const value = table$1[type][subtype]; - if (typeof value == "string") { - mimeTypes[value] = type + "/" + subtype; - } else { - for (let indexMimeType = 0; indexMimeType < value.length; indexMimeType++) { - mimeTypes[value[indexMimeType]] = type + "/" + subtype; - } - } - } - } - } - } - return mimeTypes; -})(); - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const table = []; -for (let i = 0; i < 256; i++) { - let t = i; - for (let j = 0; j < 8; j++) { - if (t & 1) { - t = (t >>> 1) ^ 0xEDB88320; - } else { - t = t >>> 1; - } - } - table[i] = t; -} - -class Crc32 { - - constructor(crc) { - this.crc = crc || -1; - } - - append(data) { - let crc = this.crc | 0; - for (let offset = 0, length = data.length | 0; offset < length; offset++) { - crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; - } - this.crc = crc; - } - - get() { - return ~this.crc; - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -class Crc32Stream extends TransformStream { - - constructor() { - const crc32 = new Crc32(); - super({ - transform(chunk) { - crc32.append(chunk); - }, - flush(controller) { - const value = new Uint8Array(4); - const dataView = new DataView(value.buffer); - dataView.setUint32(0, crc32.get()); - controller.enqueue(value); - } - }); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -function encodeText(value) { - if (typeof TextEncoder == "undefined") { - value = unescape(encodeURIComponent(value)); - const result = new Uint8Array(value.length); - for (let i = 0; i < result.length; i++) { - result[i] = value.charCodeAt(i); - } - return result; - } else { - return new TextEncoder().encode(value); - } -} - -// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl - -// deno-lint-ignore-file no-this-alias - -/* - * SJCL is open. You can use, modify and redistribute it under a BSD - * license or under the GNU GPL, version 2.0. - */ - -/** @fileOverview Javascript cryptography implementation. - * - * Crush to remove comments, shorten variable names and - * generally reduce transmission size. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */ - -/** @fileOverview Arrays of bits, encoded as arrays of Numbers. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/** - * Arrays of bits, encoded as arrays of Numbers. - * @namespace - * @description - *

- * These objects are the currency accepted by SJCL's crypto functions. - *

- * - *

- * Most of our crypto primitives operate on arrays of 4-byte words internally, - * but many of them can take arguments that are not a multiple of 4 bytes. - * This library encodes arrays of bits (whose size need not be a multiple of 8 - * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an - * array of words, 32 bits at a time. Since the words are double-precision - * floating point numbers, they fit some extra data. We use this (in a private, - * possibly-changing manner) to encode the number of bits actually present - * in the last word of the array. - *

- * - *

- * Because bitwise ops clear this out-of-band data, these arrays can be passed - * to ciphers like AES which want arrays of words. - *

- */ -const bitArray = { - /** - * Concatenate two bit arrays. - * @param {bitArray} a1 The first array. - * @param {bitArray} a2 The second array. - * @return {bitArray} The concatenation of a1 and a2. - */ - concat(a1, a2) { - if (a1.length === 0 || a2.length === 0) { - return a1.concat(a2); - } - - const last = a1[a1.length - 1], shift = bitArray.getPartial(last); - if (shift === 32) { - return a1.concat(a2); - } else { - return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1)); - } - }, - - /** - * Find the length of an array of bits. - * @param {bitArray} a The array. - * @return {Number} The length of a, in bits. - */ - bitLength(a) { - const l = a.length; - if (l === 0) { - return 0; - } - const x = a[l - 1]; - return (l - 1) * 32 + bitArray.getPartial(x); - }, - - /** - * Truncate an array. - * @param {bitArray} a The array. - * @param {Number} len The length to truncate to, in bits. - * @return {bitArray} A new array, truncated to len bits. - */ - clamp(a, len) { - if (a.length * 32 < len) { - return a; - } - a = a.slice(0, Math.ceil(len / 32)); - const l = a.length; - len = len & 31; - if (l > 0 && len) { - a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1); - } - return a; - }, - - /** - * Make a partial word for a bit array. - * @param {Number} len The number of bits in the word. - * @param {Number} x The bits. - * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side. - * @return {Number} The partial word. - */ - partial(len, x, _end) { - if (len === 32) { - return x; - } - return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000; - }, - - /** - * Get the number of bits used by a partial word. - * @param {Number} x The partial word. - * @return {Number} The number of bits used by the partial word. - */ - getPartial(x) { - return Math.round(x / 0x10000000000) || 32; - }, - - /** Shift an array right. - * @param {bitArray} a The array to shift. - * @param {Number} shift The number of bits to shift. - * @param {Number} [carry=0] A byte to carry in - * @param {bitArray} [out=[]] An array to prepend to the output. - * @private - */ - _shiftRight(a, shift, carry, out) { - if (out === undefined) { - out = []; - } - - for (; shift >= 32; shift -= 32) { - out.push(carry); - carry = 0; - } - if (shift === 0) { - return out.concat(a); - } - - for (let i = 0; i < a.length; i++) { - out.push(carry | a[i] >>> shift); - carry = a[i] << (32 - shift); - } - const last2 = a.length ? a[a.length - 1] : 0; - const shift2 = bitArray.getPartial(last2); - out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1)); - return out; - } -}; - -/** @fileOverview Bit array codec implementations. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/** - * Arrays of bytes - * @namespace - */ -const codec = { - bytes: { - /** Convert from a bitArray to an array of bytes. */ - fromBits(arr) { - const bl = bitArray.bitLength(arr); - const byteLength = bl / 8; - const out = new Uint8Array(byteLength); - let tmp; - for (let i = 0; i < byteLength; i++) { - if ((i & 3) === 0) { - tmp = arr[i / 4]; - } - out[i] = tmp >>> 24; - tmp <<= 8; - } - return out; - }, - /** Convert from an array of bytes to a bitArray. */ - toBits(bytes) { - const out = []; - let i; - let tmp = 0; - for (i = 0; i < bytes.length; i++) { - tmp = tmp << 8 | bytes[i]; - if ((i & 3) === 3) { - out.push(tmp); - tmp = 0; - } - } - if (i & 3) { - out.push(bitArray.partial(8 * (i & 3), tmp)); - } - return out; - } - } -}; - -const hash = {}; - -/** - * Context for a SHA-1 operation in progress. - * @constructor - */ -hash.sha1 = class { - constructor(hash) { - const sha1 = this; - /** - * The hash's block size, in bits. - * @constant - */ - sha1.blockSize = 512; - /** - * The SHA-1 initialization vector. - * @private - */ - sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]; - /** - * The SHA-1 hash key. - * @private - */ - sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6]; - if (hash) { - sha1._h = hash._h.slice(0); - sha1._buffer = hash._buffer.slice(0); - sha1._length = hash._length; - } else { - sha1.reset(); - } - } - - /** - * Reset the hash state. - * @return this - */ - reset() { - const sha1 = this; - sha1._h = sha1._init.slice(0); - sha1._buffer = []; - sha1._length = 0; - return sha1; - } - - /** - * Input several words to the hash. - * @param {bitArray|String} data the data to hash. - * @return this - */ - update(data) { - const sha1 = this; - if (typeof data === "string") { - data = codec.utf8String.toBits(data); - } - const b = sha1._buffer = bitArray.concat(sha1._buffer, data); - const ol = sha1._length; - const nl = sha1._length = ol + bitArray.bitLength(data); - if (nl > 9007199254740991) { - throw new Error("Cannot hash more than 2^53 - 1 bits"); - } - const c = new Uint32Array(b); - let j = 0; - for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl; - i += sha1.blockSize) { - sha1._block(c.subarray(16 * j, 16 * (j + 1))); - j += 1; - } - b.splice(0, 16 * j); - return sha1; - } - - /** - * Complete hashing and output the hash value. - * @return {bitArray} The hash value, an array of 5 big-endian words. TODO - */ - finalize() { - const sha1 = this; - let b = sha1._buffer; - const h = sha1._h; - - // Round out and push the buffer - b = bitArray.concat(b, [bitArray.partial(1, 1)]); - // Round out the buffer to a multiple of 16 words, less the 2 length words. - for (let i = b.length + 2; i & 15; i++) { - b.push(0); - } - - // append the length - b.push(Math.floor(sha1._length / 0x100000000)); - b.push(sha1._length | 0); - - while (b.length) { - sha1._block(b.splice(0, 16)); - } - - sha1.reset(); - return h; - } - - /** - * The SHA-1 logical functions f(0), f(1), ..., f(79). - * @private - */ - _f(t, b, c, d) { - if (t <= 19) { - return (b & c) | (~b & d); - } else if (t <= 39) { - return b ^ c ^ d; - } else if (t <= 59) { - return (b & c) | (b & d) | (c & d); - } else if (t <= 79) { - return b ^ c ^ d; - } - } - - /** - * Circular left-shift operator. - * @private - */ - _S(n, x) { - return (x << n) | (x >>> 32 - n); - } - - /** - * Perform one cycle of SHA-1. - * @param {Uint32Array|bitArray} words one block of words. - * @private - */ - _block(words) { - const sha1 = this; - const h = sha1._h; - // When words is passed to _block, it has 16 elements. SHA1 _block - // function extends words with new elements (at the end there are 80 elements). - // The problem is that if we use Uint32Array instead of Array, - // the length of Uint32Array cannot be changed. Thus, we replace words with a - // normal Array here. - const w = Array(80); // do not use Uint32Array here as the instantiation is slower - for (let j = 0; j < 16; j++) { - w[j] = words[j]; - } - - let a = h[0]; - let b = h[1]; - let c = h[2]; - let d = h[3]; - let e = h[4]; - - for (let t = 0; t <= 79; t++) { - if (t >= 16) { - w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]); - } - const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] + - sha1._key[Math.floor(t / 20)]) | 0; - e = d; - d = c; - c = sha1._S(30, b); - b = a; - a = tmp; - } - - h[0] = (h[0] + a) | 0; - h[1] = (h[1] + b) | 0; - h[2] = (h[2] + c) | 0; - h[3] = (h[3] + d) | 0; - h[4] = (h[4] + e) | 0; - } -}; - -/** @fileOverview Low-level AES implementation. - * - * This file contains a low-level implementation of AES, optimized for - * size and for efficiency on several browsers. It is based on - * OpenSSL's aes_core.c, a public-domain implementation by Vincent - * Rijmen, Antoon Bosselaers and Paulo Barreto. - * - * An older version of this implementation is available in the public - * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh, - * Stanford University 2008-2010 and BSD-licensed for liability - * reasons. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -const cipher = {}; - -/** - * Schedule out an AES key for both encryption and decryption. This - * is a low-level class. Use a cipher mode to do bulk encryption. - * - * @constructor - * @param {Array} key The key as an array of 4, 6 or 8 words. - */ -cipher.aes = class { - constructor(key) { - /** - * The expanded S-box and inverse S-box tables. These will be computed - * on the client so that we don't have to send them down the wire. - * - * There are two tables, _tables[0] is for encryption and - * _tables[1] is for decryption. - * - * The first 4 sub-tables are the expanded S-box with MixColumns. The - * last (_tables[01][4]) is the S-box itself. - * - * @private - */ - const aes = this; - aes._tables = [[[], [], [], [], []], [[], [], [], [], []]]; - - if (!aes._tables[0][0][0]) { - aes._precompute(); - } - - const sbox = aes._tables[0][4]; - const decTable = aes._tables[1]; - const keyLen = key.length; - - let i, encKey, decKey, rcon = 1; - - if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) { - throw new Error("invalid aes key size"); - } - - aes._key = [encKey = key.slice(0), decKey = []]; - - // schedule encryption keys - for (i = keyLen; i < 4 * keyLen + 28; i++) { - let tmp = encKey[i - 1]; - - // apply sbox - if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) { - tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]; - - // shift rows and add rcon - if (i % keyLen === 0) { - tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24; - rcon = rcon << 1 ^ (rcon >> 7) * 283; - } - } - - encKey[i] = encKey[i - keyLen] ^ tmp; - } - - // schedule decryption keys - for (let j = 0; i; j++, i--) { - const tmp = encKey[j & 3 ? i : i - 4]; - if (i <= 4 || j < 4) { - decKey[j] = tmp; - } else { - decKey[j] = decTable[0][sbox[tmp >>> 24]] ^ - decTable[1][sbox[tmp >> 16 & 255]] ^ - decTable[2][sbox[tmp >> 8 & 255]] ^ - decTable[3][sbox[tmp & 255]]; - } - } - } - // public - /* Something like this might appear here eventually - name: "AES", - blockSize: 4, - keySizes: [4,6,8], - */ - - /** - * Encrypt an array of 4 big-endian words. - * @param {Array} data The plaintext. - * @return {Array} The ciphertext. - */ - encrypt(data) { - return this._crypt(data, 0); - } - - /** - * Decrypt an array of 4 big-endian words. - * @param {Array} data The ciphertext. - * @return {Array} The plaintext. - */ - decrypt(data) { - return this._crypt(data, 1); - } - - /** - * Expand the S-box tables. - * - * @private - */ - _precompute() { - const encTable = this._tables[0]; - const decTable = this._tables[1]; - const sbox = encTable[4]; - const sboxInv = decTable[4]; - const d = []; - const th = []; - let xInv, x2, x4, x8; - - // Compute double and third tables - for (let i = 0; i < 256; i++) { - th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i; - } - - for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) { - // Compute sbox - let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4; - s = s >> 8 ^ s & 255 ^ 99; - sbox[x] = s; - sboxInv[s] = x; - - // Compute MixColumns - x8 = d[x4 = d[x2 = d[x]]]; - let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100; - let tEnc = d[s] * 0x101 ^ s * 0x1010100; - - for (let i = 0; i < 4; i++) { - encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8; - decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8; - } - } - - // Compactify. Considerable speedup on Firefox. - for (let i = 0; i < 5; i++) { - encTable[i] = encTable[i].slice(0); - decTable[i] = decTable[i].slice(0); - } - } - - /** - * Encryption and decryption core. - * @param {Array} input Four words to be encrypted or decrypted. - * @param dir The direction, 0 for encrypt and 1 for decrypt. - * @return {Array} The four encrypted or decrypted words. - * @private - */ - _crypt(input, dir) { - if (input.length !== 4) { - throw new Error("invalid aes block size"); - } - - const key = this._key[dir]; - - const nInnerRounds = key.length / 4 - 2; - const out = [0, 0, 0, 0]; - const table = this._tables[dir]; - - // load up the tables - const t0 = table[0]; - const t1 = table[1]; - const t2 = table[2]; - const t3 = table[3]; - const sbox = table[4]; - - // state variables a,b,c,d are loaded with pre-whitened data - let a = input[0] ^ key[0]; - let b = input[dir ? 3 : 1] ^ key[1]; - let c = input[2] ^ key[2]; - let d = input[dir ? 1 : 3] ^ key[3]; - let kIndex = 4; - let a2, b2, c2; - - // Inner rounds. Cribbed from OpenSSL. - for (let i = 0; i < nInnerRounds; i++) { - a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex]; - b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]; - c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]; - d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]; - kIndex += 4; - a = a2; b = b2; c = c2; - } - - // Last round. - for (let i = 0; i < 4; i++) { - out[dir ? 3 & -i : i] = - sbox[a >>> 24] << 24 ^ - sbox[b >> 16 & 255] << 16 ^ - sbox[c >> 8 & 255] << 8 ^ - sbox[d & 255] ^ - key[kIndex++]; - a2 = a; a = b; b = c; c = d; d = a2; - } - - return out; - } -}; - -/** - * Random values - * @namespace - */ -const random = { - /** - * Generate random words with pure js, cryptographically not as strong & safe as native implementation. - * @param {TypedArray} typedArray The array to fill. - * @return {TypedArray} The random values. - */ - getRandomValues(typedArray) { - const words = new Uint32Array(typedArray.buffer); - const r = (m_w) => { - let m_z = 0x3ade68b1; - const mask = 0xffffffff; - return function () { - m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; - m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; - const result = ((((m_z << 0x10) + m_w) & mask) / 0x100000000) + .5; - return result * (Math.random() > .5 ? 1 : -1); - }; - }; - for (let i = 0, rcache; i < typedArray.length; i += 4) { - const _r = r((rcache || Math.random()) * 0x100000000); - rcache = _r() * 0x3ade67b7; - words[i / 4] = (_r() * 0x100000000) | 0; - } - return typedArray; - } -}; - -/** @fileOverview CTR mode implementation. - * - * Special thanks to Roy Nicholson for pointing out a bug in our - * implementation. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/** Brian Gladman's CTR Mode. -* @constructor -* @param {Object} _prf The aes instance to generate key. -* @param {bitArray} _iv The iv for ctr mode, it must be 128 bits. -*/ - -const mode = {}; - -/** - * Brian Gladman's CTR Mode. - * @namespace - */ -mode.ctrGladman = class { - constructor(prf, iv) { - this._prf = prf; - this._initIv = iv; - this._iv = iv; - } - - reset() { - this._iv = this._initIv; - } - - /** Input some data to calculate. - * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last. - */ - update(data) { - return this.calculate(this._prf, data, this._iv); - } - - incWord(word) { - if (((word >> 24) & 0xff) === 0xff) { //overflow - let b1 = (word >> 16) & 0xff; - let b2 = (word >> 8) & 0xff; - let b3 = word & 0xff; - - if (b1 === 0xff) { // overflow b1 - b1 = 0; - if (b2 === 0xff) { - b2 = 0; - if (b3 === 0xff) { - b3 = 0; - } else { - ++b3; - } - } else { - ++b2; - } - } else { - ++b1; - } - - word = 0; - word += (b1 << 16); - word += (b2 << 8); - word += b3; - } else { - word += (0x01 << 24); - } - return word; - } - - incCounter(counter) { - if ((counter[0] = this.incWord(counter[0])) === 0) { - // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8 - counter[1] = this.incWord(counter[1]); - } - } - - calculate(prf, data, iv) { - let l; - if (!(l = data.length)) { - return []; - } - const bl = bitArray.bitLength(data); - for (let i = 0; i < l; i += 4) { - this.incCounter(iv); - const e = prf.encrypt(iv); - data[i] ^= e[0]; - data[i + 1] ^= e[1]; - data[i + 2] ^= e[2]; - data[i + 3] ^= e[3]; - } - return bitArray.clamp(data, bl); - } -}; - -const misc = { - importKey(password) { - return new misc.hmacSha1(codec.bytes.toBits(password)); - }, - pbkdf2(prf, salt, count, length) { - count = count || 10000; - if (length < 0 || count < 0) { - throw new Error("invalid params to pbkdf2"); - } - const byteLength = ((length >> 5) + 1) << 2; - let u, ui, i, j, k; - const arrayBuffer = new ArrayBuffer(byteLength); - const out = new DataView(arrayBuffer); - let outLength = 0; - const b = bitArray; - salt = codec.bytes.toBits(salt); - for (k = 1; outLength < (byteLength || 1); k++) { - u = ui = prf.encrypt(b.concat(salt, [k])); - for (i = 1; i < count; i++) { - ui = prf.encrypt(ui); - for (j = 0; j < ui.length; j++) { - u[j] ^= ui[j]; - } - } - for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) { - out.setInt32(outLength, u[i]); - outLength += 4; - } - } - return arrayBuffer.slice(0, length / 8); - } -}; - -/** @fileOverview HMAC implementation. - * - * @author Emily Stark - * @author Mike Hamburg - * @author Dan Boneh - */ - -/** HMAC with the specified hash function. - * @constructor - * @param {bitArray} key the key for HMAC. - * @param {Object} [Hash=hash.sha1] The hash function to use. - */ -misc.hmacSha1 = class { - - constructor(key) { - const hmac = this; - const Hash = hmac._hash = hash.sha1; - const exKey = [[], []]; - hmac._baseHash = [new Hash(), new Hash()]; - const bs = hmac._baseHash[0].blockSize / 32; - - if (key.length > bs) { - key = new Hash().update(key).finalize(); - } - - for (let i = 0; i < bs; i++) { - exKey[0][i] = key[i] ^ 0x36363636; - exKey[1][i] = key[i] ^ 0x5C5C5C5C; - } - - hmac._baseHash[0].update(exKey[0]); - hmac._baseHash[1].update(exKey[1]); - hmac._resultHash = new Hash(hmac._baseHash[0]); - } - reset() { - const hmac = this; - hmac._resultHash = new hmac._hash(hmac._baseHash[0]); - hmac._updated = false; - } - - update(data) { - const hmac = this; - hmac._updated = true; - hmac._resultHash.update(data); - } - - digest() { - const hmac = this; - const w = hmac._resultHash.finalize(); - const result = new (hmac._hash)(hmac._baseHash[1]).update(w).finalize(); - - hmac.reset(); - - return result; - } - - encrypt(data) { - if (!this._updated) { - this.update(data); - return this.digest(data); - } else { - throw new Error("encrypt on already updated hmac called!"); - } - } -}; - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != "undefined" && typeof crypto.getRandomValues == "function"; - -const ERR_INVALID_PASSWORD = "Invalid password"; -const ERR_INVALID_SIGNATURE = "Invalid signature"; -const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password"; - -function getRandomValues(array) { - if (GET_RANDOM_VALUES_SUPPORTED) { - return crypto.getRandomValues(array); - } else { - return random.getRandomValues(array); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const BLOCK_LENGTH = 16; -const RAW_FORMAT = "raw"; -const PBKDF2_ALGORITHM = { name: "PBKDF2" }; -const HASH_ALGORITHM = { name: "HMAC" }; -const HASH_FUNCTION = "SHA-1"; -const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM); -const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: 1000, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM); -const DERIVED_BITS_USAGE = ["deriveBits"]; -const SALT_LENGTH = [8, 12, 16]; -const KEY_LENGTH = [16, 24, 32]; -const SIGNATURE_LENGTH = 10; -const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0]; -const UNDEFINED_TYPE = "undefined"; -const FUNCTION_TYPE = "function"; -// deno-lint-ignore valid-typeof -const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE; -const subtle = CRYPTO_API_SUPPORTED && crypto.subtle; -const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE; -const codecBytes = codec.bytes; -const Aes = cipher.aes; -const CtrGladman = mode.ctrGladman; -const HmacSha1 = misc.hmacSha1; - -let IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE; -let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.deriveBits == FUNCTION_TYPE; - -class AESDecryptionStream extends TransformStream { - - constructor({ password, signed, encryptionStrength, checkPasswordOnly }) { - super({ - start() { - Object.assign(this, { - ready: new Promise(resolve => this.resolveReady = resolve), - password, - signed, - strength: encryptionStrength - 1, - pending: new Uint8Array() - }); - }, - async transform(chunk, controller) { - const aesCrypto = this; - const { - password, - strength, - resolveReady, - ready - } = aesCrypto; - if (password) { - await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + 2)); - chunk = subarray(chunk, SALT_LENGTH[strength] + 2); - if (checkPasswordOnly) { - controller.error(new Error(ERR_ABORT_CHECK_PASSWORD)); - } else { - resolveReady(); - } - } else { - await ready; - } - const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH)); - controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true)); - }, - async flush(controller) { - const { - signed, - ctr, - hmac, - pending, - ready - } = this; - await ready; - const chunkToDecrypt = subarray(pending, 0, pending.length - SIGNATURE_LENGTH); - const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH); - let decryptedChunkArray = new Uint8Array(); - if (chunkToDecrypt.length) { - const encryptedChunk = toBits(codecBytes, chunkToDecrypt); - hmac.update(encryptedChunk); - const decryptedChunk = ctr.update(encryptedChunk); - decryptedChunkArray = fromBits(codecBytes, decryptedChunk); - } - if (signed) { - const signature = subarray(fromBits(codecBytes, hmac.digest()), 0, SIGNATURE_LENGTH); - for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) { - if (signature[indexSignature] != originalSignature[indexSignature]) { - throw new Error(ERR_INVALID_SIGNATURE); - } - } - } - controller.enqueue(decryptedChunkArray); - } - }); - } -} - -class AESEncryptionStream extends TransformStream { - - constructor({ password, encryptionStrength }) { - // deno-lint-ignore prefer-const - let stream; - super({ - start() { - Object.assign(this, { - ready: new Promise(resolve => this.resolveReady = resolve), - password, - strength: encryptionStrength - 1, - pending: new Uint8Array() - }); - }, - async transform(chunk, controller) { - const aesCrypto = this; - const { - password, - strength, - resolveReady, - ready - } = aesCrypto; - let preamble = new Uint8Array(); - if (password) { - preamble = await createEncryptionKeys(aesCrypto, strength, password); - resolveReady(); - } else { - await ready; - } - const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH)); - output.set(preamble, 0); - controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0)); - }, - async flush(controller) { - const { - ctr, - hmac, - pending, - ready - } = this; - await ready; - let encryptedChunkArray = new Uint8Array(); - if (pending.length) { - const encryptedChunk = ctr.update(toBits(codecBytes, pending)); - hmac.update(encryptedChunk); - encryptedChunkArray = fromBits(codecBytes, encryptedChunk); - } - stream.signature = fromBits(codecBytes, hmac.digest()).slice(0, SIGNATURE_LENGTH); - controller.enqueue(concat(encryptedChunkArray, stream.signature)); - } - }); - stream = this; - } -} - -function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignature) { - const { - ctr, - hmac, - pending - } = aesCrypto; - const inputLength = input.length - paddingEnd; - if (pending.length) { - input = concat(pending, input); - output = expand(output, inputLength - (inputLength % BLOCK_LENGTH)); - } - let offset; - for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) { - const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH)); - if (verifySignature) { - hmac.update(inputChunk); - } - const outputChunk = ctr.update(inputChunk); - if (!verifySignature) { - hmac.update(outputChunk); - } - output.set(fromBits(codecBytes, outputChunk), offset + paddingStart); - } - aesCrypto.pending = subarray(input, offset); - return output; -} - -async function createDecryptionKeys(decrypt, strength, password, preamble) { - const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength])); - const passwordVerification = subarray(preamble, SALT_LENGTH[strength]); - if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) { - throw new Error(ERR_INVALID_PASSWORD); - } -} - -async function createEncryptionKeys(encrypt, strength, password) { - const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength])); - const passwordVerification = await createKeys$1(encrypt, strength, password, salt); - return concat(salt, passwordVerification); -} - -async function createKeys$1(aesCrypto, strength, password, salt) { - aesCrypto.password = null; - const encodedPassword = encodeText(password); - const baseKey = await importKey(RAW_FORMAT, encodedPassword, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE); - const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2)); - const compositeKey = new Uint8Array(derivedBits); - const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength])); - const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2)); - const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2); - Object.assign(aesCrypto, { - keys: { - key, - authentication, - passwordVerification - }, - ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)), - hmac: new HmacSha1(authentication) - }); - return passwordVerification; -} - -async function importKey(format, password, algorithm, extractable, keyUsages) { - if (IMPORT_KEY_SUPPORTED) { - try { - return await subtle.importKey(format, password, algorithm, extractable, keyUsages); - } catch (_error) { - IMPORT_KEY_SUPPORTED = false; - return misc.importKey(password); - } - } else { - return misc.importKey(password); - } -} - -async function deriveBits(algorithm, baseKey, length) { - if (DERIVE_BITS_SUPPORTED) { - try { - return await subtle.deriveBits(algorithm, baseKey, length); - } catch (_error) { - DERIVE_BITS_SUPPORTED = false; - return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length); - } - } else { - return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length); - } -} - -function concat(leftArray, rightArray) { - let array = leftArray; - if (leftArray.length + rightArray.length) { - array = new Uint8Array(leftArray.length + rightArray.length); - array.set(leftArray, 0); - array.set(rightArray, leftArray.length); - } - return array; -} - -function expand(inputArray, length) { - if (length && length > inputArray.length) { - const array = inputArray; - inputArray = new Uint8Array(length); - inputArray.set(array, 0); - } - return inputArray; -} - -function subarray(array, begin, end) { - return array.subarray(begin, end); -} - -function fromBits(codecBytes, chunk) { - return codecBytes.fromBits(chunk); -} -function toBits(codecBytes, chunk) { - return codecBytes.toBits(chunk); -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const HEADER_LENGTH = 12; - -class ZipCryptoDecryptionStream extends TransformStream { - - constructor({ password, passwordVerification, checkPasswordOnly }) { - super({ - start() { - Object.assign(this, { - password, - passwordVerification - }); - createKeys(this, password); - }, - transform(chunk, controller) { - const zipCrypto = this; - if (zipCrypto.password) { - const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH)); - zipCrypto.password = null; - if (decryptedHeader[HEADER_LENGTH - 1] != zipCrypto.passwordVerification) { - throw new Error(ERR_INVALID_PASSWORD); - } - chunk = chunk.subarray(HEADER_LENGTH); - } - if (checkPasswordOnly) { - controller.error(new Error(ERR_ABORT_CHECK_PASSWORD)); - } else { - controller.enqueue(decrypt(zipCrypto, chunk)); - } - } - }); - } -} - -class ZipCryptoEncryptionStream extends TransformStream { - - constructor({ password, passwordVerification }) { - super({ - start() { - Object.assign(this, { - password, - passwordVerification - }); - createKeys(this, password); - }, - transform(chunk, controller) { - const zipCrypto = this; - let output; - let offset; - if (zipCrypto.password) { - zipCrypto.password = null; - const header = getRandomValues(new Uint8Array(HEADER_LENGTH)); - header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification; - output = new Uint8Array(chunk.length + header.length); - output.set(encrypt(zipCrypto, header), 0); - offset = HEADER_LENGTH; - } else { - output = new Uint8Array(chunk.length); - offset = 0; - } - output.set(encrypt(zipCrypto, chunk), offset); - controller.enqueue(output); - } - }); - } -} - -function decrypt(target, input) { - const output = new Uint8Array(input.length); - for (let index = 0; index < input.length; index++) { - output[index] = getByte(target) ^ input[index]; - updateKeys(target, output[index]); - } - return output; -} - -function encrypt(target, input) { - const output = new Uint8Array(input.length); - for (let index = 0; index < input.length; index++) { - output[index] = getByte(target) ^ input[index]; - updateKeys(target, input[index]); - } - return output; -} - -function createKeys(target, password) { - const keys = [0x12345678, 0x23456789, 0x34567890]; - Object.assign(target, { - keys, - crcKey0: new Crc32(keys[0]), - crcKey2: new Crc32(keys[2]), - }); - for (let index = 0; index < password.length; index++) { - updateKeys(target, password.charCodeAt(index)); - } -} - -function updateKeys(target, byte) { - let [key0, key1, key2] = target.keys; - target.crcKey0.append([byte]); - key0 = ~target.crcKey0.get(); - key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1); - target.crcKey2.append([key1 >>> 24]); - key2 = ~target.crcKey2.get(); - target.keys = [key0, key1, key2]; -} - -function getByte(target) { - const temp = target.keys[2] | 2; - return getInt8(Math.imul(temp, (temp ^ 1)) >>> 8); -} - -function getInt8(number) { - return number & 0xFF; -} - -function getInt32(number) { - return number & 0xFFFFFFFF; -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const COMPRESSION_FORMAT = "deflate-raw"; - -class DeflateStream extends TransformStream { - - constructor(options, { chunkSize, CompressionStream, CompressionStreamNative }) { - super({}); - const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level } = options; - const stream = this; - let crc32Stream, encryptionStream; - let readable = filterEmptyChunks(super.readable); - if ((!encrypted || zipCrypto) && signed) { - [readable, crc32Stream] = readable.tee(); - crc32Stream = pipeThrough(crc32Stream, new Crc32Stream()); - } - if (compressed) { - readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStreamNative, CompressionStream); - } - if (encrypted) { - if (zipCrypto) { - readable = pipeThrough(readable, new ZipCryptoEncryptionStream(options)); - } else { - encryptionStream = new AESEncryptionStream(options); - readable = pipeThrough(readable, encryptionStream); - } - } - setReadable(stream, readable, async () => { - let signature; - if (encrypted && !zipCrypto) { - signature = encryptionStream.signature; - } - if ((!encrypted || zipCrypto) && signed) { - signature = await crc32Stream.getReader().read(); - signature = new DataView(signature.value.buffer).getUint32(0); - } - stream.signature = signature; - }); - } -} - -class InflateStream extends TransformStream { - - constructor(options, { chunkSize, DecompressionStream, DecompressionStreamNative }) { - super({}); - const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream } = options; - let crc32Stream, decryptionStream; - let readable = filterEmptyChunks(super.readable); - if (encrypted) { - if (zipCrypto) { - readable = pipeThrough(readable, new ZipCryptoDecryptionStream(options)); - } else { - decryptionStream = new AESDecryptionStream(options); - readable = pipeThrough(readable, decryptionStream); - } - } - if (compressed) { - readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize }, DecompressionStreamNative, DecompressionStream); - } - if ((!encrypted || zipCrypto) && signed) { - [readable, crc32Stream] = readable.tee(); - crc32Stream = pipeThrough(crc32Stream, new Crc32Stream()); - } - setReadable(this, readable, async () => { - if ((!encrypted || zipCrypto) && signed) { - const streamSignature = await crc32Stream.getReader().read(); - const dataViewSignature = new DataView(streamSignature.value.buffer); - if (signature != dataViewSignature.getUint32(0, false)) { - throw new Error(ERR_INVALID_SIGNATURE); - } - } - }); - } -} - -function filterEmptyChunks(readable) { - return pipeThrough(readable, new TransformStream({ - transform(chunk, controller) { - if (chunk && chunk.length) { - controller.enqueue(chunk); - } - } - })); -} - -function setReadable(stream, readable, flush) { - readable = pipeThrough(readable, new TransformStream({ flush })); - Object.defineProperty(stream, "readable", { - get() { - return readable; - } - }); -} - -function pipeThroughCommpressionStream(readable, useCompressionStream, options, CodecStreamNative, CodecStream) { - try { - const CompressionStream = useCompressionStream && CodecStreamNative ? CodecStreamNative : CodecStream; - readable = pipeThrough(readable, new CompressionStream(COMPRESSION_FORMAT, options)); - } catch (error) { - if (useCompressionStream) { - readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options)); - } else { - throw error; - } - } - return readable; -} - -function pipeThrough(readable, transformStream) { - return readable.pipeThrough(transformStream); -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const MESSAGE_EVENT_TYPE = "message"; -const MESSAGE_START = "start"; -const MESSAGE_PULL = "pull"; -const MESSAGE_DATA = "data"; -const MESSAGE_ACK_DATA = "ack"; -const MESSAGE_CLOSE = "close"; -const CODEC_DEFLATE = "deflate"; -const CODEC_INFLATE = "inflate"; - -class CodecStream extends TransformStream { - - constructor(options, config) { - super({}); - const codec = this; - const { codecType } = options; - let Stream; - if (codecType.startsWith(CODEC_DEFLATE)) { - Stream = DeflateStream; - } else if (codecType.startsWith(CODEC_INFLATE)) { - Stream = InflateStream; - } - let size = 0; - const stream = new Stream(options, config); - const readable = super.readable; - const transformStream = new TransformStream({ - transform(chunk, controller) { - if (chunk && chunk.length) { - size += chunk.length; - controller.enqueue(chunk); - } - }, - flush() { - const { signature } = stream; - Object.assign(codec, { - signature, - size - }); - } - }); - Object.defineProperty(codec, "readable", { - get() { - return readable.pipeThrough(stream).pipeThrough(transformStream); - } - }); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// deno-lint-ignore valid-typeof -const WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE$1; - -class CodecWorker { - - constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, scripts }, onTaskFinished) { - const { signal } = streamOptions; - Object.assign(workerData, { - busy: true, - readable: readable.pipeThrough(new ProgressWatcherStream(readable, streamOptions, config), { signal }), - writable, - options: Object.assign({}, options), - scripts, - transferStreams, - terminate() { - const { worker, busy } = workerData; - if (worker && !busy) { - worker.terminate(); - workerData.interface = null; - } - }, - onTaskFinished() { - workerData.busy = false; - onTaskFinished(workerData); - } - }); - return (useWebWorkers && WEB_WORKERS_SUPPORTED ? createWebWorkerInterface : createWorkerInterface)(workerData, config); - } -} - -class ProgressWatcherStream extends TransformStream { - - constructor(readableSource, { onstart, onprogress, size, onend }, { chunkSize }) { - let chunkOffset = 0; - super({ - start() { - if (onstart) { - callHandler(onstart, size); - } - }, - async transform(chunk, controller) { - chunkOffset += chunk.length; - if (onprogress) { - await callHandler(onprogress, chunkOffset, size); - } - controller.enqueue(chunk); - }, - flush() { - readableSource.size = chunkOffset; - if (onend) { - callHandler(onend, chunkOffset); - } - } - }, { highWaterMark: 1, size: () => chunkSize }); - } -} - -async function callHandler(handler, ...parameters) { - try { - await handler(...parameters); - } catch (_error) { - // ignored - } -} - -function createWorkerInterface(workerData, config) { - return { - run: () => runWorker$1(workerData, config) - }; -} - -function createWebWorkerInterface(workerData, { baseURL, chunkSize }) { - if (!workerData.interface) { - Object.assign(workerData, { - worker: getWebWorker(workerData.scripts[0], baseURL, workerData), - interface: { - run: () => runWebWorker(workerData, { chunkSize }) - } - }); - } - return workerData.interface; -} - -async function runWorker$1({ options, readable, writable, onTaskFinished }, config) { - const codecStream = new CodecStream(options, config); - try { - await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true }); - const { - signature, - size - } = codecStream; - return { - signature, - size - }; - } finally { - onTaskFinished(); - } -} - -async function runWebWorker(workerData, config) { - let resolveResult, rejectResult; - const result = new Promise((resolve, reject) => { - resolveResult = resolve; - rejectResult = reject; - }); - Object.assign(workerData, { - reader: null, - writer: null, - resolveResult, - rejectResult, - result - }); - const { readable, options, scripts } = workerData; - const { writable, closed } = watchClosedStream(workerData.writable); - const streamsTransferred = sendMessage({ - type: MESSAGE_START, - scripts: scripts.slice(1), - options, - config, - readable, - writable - }, workerData); - if (!streamsTransferred) { - Object.assign(workerData, { - reader: readable.getReader(), - writer: writable.getWriter() - }); - } - const resultValue = await result; - try { - await writable.close(); - } catch (_error) { - // ignored - } - await closed; - return resultValue; -} - -function watchClosedStream(writableSource) { - const writer = writableSource.getWriter(); - let resolveStreamClosed; - const closed = new Promise(resolve => resolveStreamClosed = resolve); - const writable = new WritableStream({ - async write(chunk) { - await writer.ready; - await writer.write(chunk); - }, - close() { - writer.releaseLock(); - resolveStreamClosed(); - }, - abort(reason) { - return writer.abort(reason); - } - }); - return { writable, closed }; -} - -let classicWorkersSupported = true; -let transferStreamsSupported = true; - -function getWebWorker(url, baseURL, workerData) { - const workerOptions = { type: "module" }; - let scriptUrl, worker; - // deno-lint-ignore valid-typeof - if (typeof url == FUNCTION_TYPE$1) { - url = url(); - } - try { - scriptUrl = new URL(url, baseURL); - } catch (_error) { - scriptUrl = url; - } - if (classicWorkersSupported) { - try { - worker = new Worker(scriptUrl); - } catch (_error) { - classicWorkersSupported = false; - worker = new Worker(scriptUrl, workerOptions); - } - } else { - worker = new Worker(scriptUrl, workerOptions); - } - worker.addEventListener(MESSAGE_EVENT_TYPE, event => onMessage(event, workerData)); - return worker; -} - -function sendMessage(message, { worker, writer, onTaskFinished, transferStreams }) { - try { - let { value, readable, writable } = message; - const transferables = []; - if (value) { - const { buffer, length } = value; - if (length != buffer.byteLength) { - value = new Uint8Array(value); - } - message.value = value.buffer; - transferables.push(message.value); - } - if (transferStreams && transferStreamsSupported) { - if (readable) { - transferables.push(readable); - } - if (writable) { - transferables.push(writable); - } - } else { - message.readable = message.writable = null; - } - if (transferables.length) { - try { - worker.postMessage(message, transferables); - return true; - } catch (_error) { - transferStreamsSupported = false; - message.readable = message.writable = null; - worker.postMessage(message); - } - } else { - worker.postMessage(message); - } - } catch (error) { - if (writer) { - writer.releaseLock(); - } - onTaskFinished(); - throw error; - } -} - -async function onMessage({ data }, workerData) { - const { type, value, messageId, result, error } = data; - const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData; - try { - if (error) { - const { message, stack, code, name } = error; - const responseError = new Error(message); - Object.assign(responseError, { stack, code, name }); - close(responseError); - } else { - if (type == MESSAGE_PULL) { - const { value, done } = await reader.read(); - sendMessage({ type: MESSAGE_DATA, value, done, messageId }, workerData); - } - if (type == MESSAGE_DATA) { - await writer.ready; - await writer.write(new Uint8Array(value)); - sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData); - } - if (type == MESSAGE_CLOSE) { - close(null, result); - } - } - } catch (error) { - close(error); - } - - function close(error, result) { - if (error) { - rejectResult(error); - } else { - resolveResult(result); - } - if (writer) { - writer.releaseLock(); - } - onTaskFinished(); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -let pool = []; -const pendingRequests = []; - -let indexWorker = 0; - -async function runWorker(stream, workerOptions) { - const { options, config } = workerOptions; - const { transferStreams, useWebWorkers, useCompressionStream, codecType, compressed, signed, encrypted } = options; - const { workerScripts, maxWorkers, terminateWorkerTimeout } = config; - workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE; - const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams; - workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers)); - workerOptions.scripts = workerOptions.useWebWorkers && workerScripts ? workerScripts[codecType] : []; - options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream); - let worker; - const workerData = pool.find(workerData => !workerData.busy); - if (workerData) { - clearTerminateTimeout(workerData); - worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished); - } else if (pool.length < maxWorkers) { - const workerData = { indexWorker }; - indexWorker++; - pool.push(workerData); - worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished); - } else { - worker = await new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions })); - } - return worker.run(); - - function onTaskFinished(workerData) { - if (pendingRequests.length) { - const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1); - resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished)); - } else if (workerData.worker) { - clearTerminateTimeout(workerData); - if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) { - workerData.terminateTimeout = setTimeout(() => { - pool = pool.filter(data => data != workerData); - workerData.terminate(); - }, terminateWorkerTimeout); - } - } else { - pool = pool.filter(data => data != workerData); - } - } -} - -function clearTerminateTimeout(workerData) { - const { terminateTimeout } = workerData; - if (terminateTimeout) { - clearTimeout(terminateTimeout); - workerData.terminateTimeout = null; - } -} - -function e(e){const t=()=>URL.createObjectURL(new Blob(['const{Array:e,Object:t,Number:n,Math:r,Error:s,Uint8Array:i,Uint16Array:o,Uint32Array:c,Int32Array:f,Map:a,DataView:l,Promise:u,TextEncoder:w,crypto:h,postMessage:d,TransformStream:p,ReadableStream:y,WritableStream:m,CompressionStream:b,DecompressionStream:g}=self;class k{constructor(e){return class extends p{constructor(t,n){const r=new e(n);super({transform(e,t){t.enqueue(r.append(e))},flush(e){const t=r.flush();t&&e.enqueue(t)}})}}}}const v=[];for(let e=0;256>e;e++){let t=e;for(let e=0;8>e;e++)1&t?t=t>>>1^3988292384:t>>>=1;v[e]=t}class S{constructor(e){this.t=e||-1}append(e){let t=0|this.t;for(let n=0,r=0|e.length;r>n;n++)t=t>>>8^v[255&(t^e[n])];this.t=t}get(){return~this.t}}class z extends p{constructor(){const e=new S;super({transform(t){e.append(t)},flush(t){const n=new i(4);new l(n.buffer).setUint32(0,e.get()),t.enqueue(n)}})}}const C={concat(e,t){if(0===e.length||0===t.length)return e.concat(t);const n=e[e.length-1],r=C.i(n);return 32===r?e.concat(t):C.o(t,r,0|n,e.slice(0,e.length-1))},l(e){const t=e.length;if(0===t)return 0;const n=e[t-1];return 32*(t-1)+C.i(n)},u(e,t){if(32*e.length0&&t&&(e[n-1]=C.h(t,e[n-1]&2147483648>>t-1,1)),e},h:(e,t,n)=>32===e?t:(n?0|t:t<<32-e)+1099511627776*e,i:e=>r.round(e/1099511627776)||32,o(e,t,n,r){for(void 0===r&&(r=[]);t>=32;t-=32)r.push(n),n=0;if(0===t)return r.concat(e);for(let s=0;s>>t),n=e[s]<<32-t;const s=e.length?e[e.length-1]:0,i=C.i(s);return r.push(C.h(t+i&31,t+i>32?n:r.pop(),1)),r}},x={p:{m(e){const t=C.l(e)/8,n=new i(t);let r;for(let s=0;t>s;s++)0==(3&s)&&(r=e[s/4]),n[s]=r>>>24,r<<=8;return n},g(e){const t=[];let n,r=0;for(n=0;n9007199254740991)throw new s("Cannot hash more than 2^53 - 1 bits");const o=new c(n);let f=0;for(let e=t.blockSize+r-(t.blockSize+r&t.blockSize-1);i>=e;e+=t.blockSize)t.I(o.subarray(16*f,16*(f+1))),f+=1;return n.splice(0,16*f),t}D(){const e=this;let t=e.C;const n=e.S;t=C.concat(t,[C.h(1,1)]);for(let e=t.length+2;15&e;e++)t.push(0);for(t.push(r.floor(e._/4294967296)),t.push(0|e._);t.length;)e.I(t.splice(0,16));return e.reset(),n}V(e,t,n,r){return e>19?e>39?e>59?e>79?void 0:t^n^r:t&n|t&r|n&r:t^n^r:t&n|~t&r}P(e,t){return t<>>32-e}I(t){const n=this,s=n.S,i=e(80);for(let e=0;16>e;e++)i[e]=t[e];let o=s[0],c=s[1],f=s[2],a=s[3],l=s[4];for(let e=0;79>=e;e++){16>e||(i[e]=n.P(1,i[e-3]^i[e-8]^i[e-14]^i[e-16]));const t=n.P(5,o)+n.V(e,c,f,a)+l+i[e]+n.v[r.floor(e/20)]|0;l=a,a=f,f=n.P(30,c),c=o,o=t}s[0]=s[0]+o|0,s[1]=s[1]+c|0,s[2]=s[2]+f|0,s[3]=s[3]+a|0,s[4]=s[4]+l|0}},A={getRandomValues(e){const t=new c(e.buffer),n=e=>{let t=987654321;const n=4294967295;return()=>(t=36969*(65535&t)+(t>>16)&n,(((t<<16)+(e=18e3*(65535&e)+(e>>16)&n)&n)/4294967296+.5)*(r.random()>.5?1:-1))};for(let s,i=0;inew I.R(x.p.g(e)),B(e,t,n,r){if(n=n||1e4,0>r||0>n)throw new s("invalid params to pbkdf2");const i=1+(r>>5)<<2;let o,c,f,a,u;const w=new ArrayBuffer(i),h=new l(w);let d=0;const p=C;for(t=x.p.g(t),u=1;(i||1)>d;u++){for(o=c=e.encrypt(p.concat(t,[u])),f=1;n>f;f++)for(c=e.encrypt(c),a=0;ad&&fs&&(e=(new n).update(e).D());for(let t=0;s>t;t++)r[0][t]=909522486^e[t],r[1][t]=1549556828^e[t];t.K[0].update(r[0]),t.K[1].update(r[1]),t.U=new n(t.K[0])}reset(){const e=this;e.U=new e.M(e.K[0]),e.N=!1}update(e){this.N=!0,this.U.update(e)}digest(){const e=this,t=e.U.D(),n=new e.M(e.K[1]).update(t).D();return e.reset(),n}encrypt(e){if(this.N)throw new s("encrypt on already updated hmac called!");return this.update(e),this.digest(e)}}},D=void 0!==h&&"function"==typeof h.getRandomValues,V="Invalid password",P="Invalid signature",R="zipjs-abort-check-password";function B(e){return D?h.getRandomValues(e):A.getRandomValues(e)}const E=16,M={name:"PBKDF2"},K=t.assign({hash:{name:"HMAC"}},M),U=t.assign({iterations:1e3,hash:{name:"SHA-1"}},M),N=["deriveBits"],O=[8,12,16],T=[16,24,32],W=10,j=[0,0,0,0],H="undefined",L="function",F=typeof h!=H,q=F&&h.subtle,G=F&&typeof q!=H,J=x.p,Q=class{constructor(e){const t=this;t.O=[[[],[],[],[],[]],[[],[],[],[],[]]],t.O[0][0][0]||t.T();const n=t.O[0][4],r=t.O[1],i=e.length;let o,c,f,a=1;if(4!==i&&6!==i&&8!==i)throw new s("invalid aes key size");for(t.v=[c=e.slice(0),f=[]],o=i;4*i+28>o;o++){let e=c[o-1];(o%i==0||8===i&&o%i==4)&&(e=n[e>>>24]<<24^n[e>>16&255]<<16^n[e>>8&255]<<8^n[255&e],o%i==0&&(e=e<<8^e>>>24^a<<24,a=a<<1^283*(a>>7))),c[o]=c[o-i]^e}for(let e=0;o;e++,o--){const t=c[3&e?o:o-4];f[e]=4>=o||4>e?t:r[0][n[t>>>24]]^r[1][n[t>>16&255]]^r[2][n[t>>8&255]]^r[3][n[255&t]]}}encrypt(e){return this.W(e,0)}decrypt(e){return this.W(e,1)}T(){const e=this.O[0],t=this.O[1],n=e[4],r=t[4],s=[],i=[];let o,c,f,a;for(let e=0;256>e;e++)i[(s[e]=e<<1^283*(e>>7))^e]=e;for(let l=o=0;!n[l];l^=c||1,o=i[o]||1){let i=o^o<<1^o<<2^o<<3^o<<4;i=i>>8^255&i^99,n[l]=i,r[i]=l,a=s[f=s[c=s[l]]];let u=16843009*a^65537*f^257*c^16843008*l,w=257*s[i]^16843008*i;for(let n=0;4>n;n++)e[n][l]=w=w<<24^w>>>8,t[n][i]=u=u<<24^u>>>8}for(let n=0;5>n;n++)e[n]=e[n].slice(0),t[n]=t[n].slice(0)}W(e,t){if(4!==e.length)throw new s("invalid aes block size");const n=this.v[t],r=n.length/4-2,i=[0,0,0,0],o=this.O[t],c=o[0],f=o[1],a=o[2],l=o[3],u=o[4];let w,h,d,p=e[0]^n[0],y=e[t?3:1]^n[1],m=e[2]^n[2],b=e[t?1:3]^n[3],g=4;for(let e=0;r>e;e++)w=c[p>>>24]^f[y>>16&255]^a[m>>8&255]^l[255&b]^n[g],h=c[y>>>24]^f[m>>16&255]^a[b>>8&255]^l[255&p]^n[g+1],d=c[m>>>24]^f[b>>16&255]^a[p>>8&255]^l[255&y]^n[g+2],b=c[b>>>24]^f[p>>16&255]^a[y>>8&255]^l[255&m]^n[g+3],g+=4,p=w,y=h,m=d;for(let e=0;4>e;e++)i[t?3&-e:e]=u[p>>>24]<<24^u[y>>16&255]<<16^u[m>>8&255]<<8^u[255&b]^n[g++],w=p,p=y,y=m,m=b,b=w;return i}},X=class{constructor(e,t){this.j=e,this.H=t,this.L=t}reset(){this.L=this.H}update(e){return this.F(this.j,e,this.L)}q(e){if(255==(e>>24&255)){let t=e>>16&255,n=e>>8&255,r=255&e;255===t?(t=0,255===n?(n=0,255===r?r=0:++r):++n):++t,e=0,e+=t<<16,e+=n<<8,e+=r}else e+=1<<24;return e}G(e){0===(e[0]=this.q(e[0]))&&(e[1]=this.q(e[1]))}F(e,t,n){let r;if(!(r=t.length))return[];const s=C.l(t);for(let s=0;r>s;s+=4){this.G(n);const r=e.encrypt(n);t[s]^=r[0],t[s+1]^=r[1],t[s+2]^=r[2],t[s+3]^=r[3]}return C.u(t,s)}},Y=I.R;let Z=F&&G&&typeof q.importKey==L,$=F&&G&&typeof q.deriveBits==L;class ee extends p{constructor({password:e,signed:n,encryptionStrength:r,checkPasswordOnly:o}){super({start(){t.assign(this,{ready:new u((e=>this.J=e)),password:e,signed:n,X:r-1,pending:new i})},async transform(e,t){const n=this,{password:r,X:c,J:f,ready:a}=n;r?(await(async(e,t,n,r)=>{const i=await re(e,t,n,ie(r,0,O[t])),o=ie(r,O[t]);if(i[0]!=o[0]||i[1]!=o[1])throw new s(V)})(n,c,r,ie(e,0,O[c]+2)),e=ie(e,O[c]+2),o?t.error(new s(R)):f()):await a;const l=new i(e.length-W-(e.length-W)%E);t.enqueue(ne(n,e,l,0,W,!0))},async flush(e){const{signed:t,Y:n,Z:r,pending:o,ready:c}=this;await c;const f=ie(o,0,o.length-W),a=ie(o,o.length-W);let l=new i;if(f.length){const e=ce(J,f);r.update(e);const t=n.update(e);l=oe(J,t)}if(t){const e=ie(oe(J,r.digest()),0,W);for(let t=0;W>t;t++)if(e[t]!=a[t])throw new s(P)}e.enqueue(l)}})}}class te extends p{constructor({password:e,encryptionStrength:n}){let r;super({start(){t.assign(this,{ready:new u((e=>this.J=e)),password:e,X:n-1,pending:new i})},async transform(e,t){const n=this,{password:r,X:s,J:o,ready:c}=n;let f=new i;r?(f=await(async(e,t,n)=>{const r=B(new i(O[t]));return se(r,await re(e,t,n,r))})(n,s,r),o()):await c;const a=new i(f.length+e.length-e.length%E);a.set(f,0),t.enqueue(ne(n,e,a,f.length,0))},async flush(e){const{Y:t,Z:n,pending:s,ready:o}=this;await o;let c=new i;if(s.length){const e=t.update(ce(J,s));n.update(e),c=oe(J,e)}r.signature=oe(J,n.digest()).slice(0,W),e.enqueue(se(c,r.signature))}}),r=this}}function ne(e,t,n,r,s,o){const{Y:c,Z:f,pending:a}=e,l=t.length-s;let u;for(a.length&&(t=se(a,t),n=((e,t)=>{if(t&&t>e.length){const n=e;(e=new i(t)).set(n,0)}return e})(n,l-l%E)),u=0;l-E>=u;u+=E){const e=ce(J,ie(t,u,u+E));o&&f.update(e);const s=c.update(e);o||f.update(s),n.set(oe(J,s),u+r)}return e.pending=ie(t,u),n}async function re(n,r,s,o){n.password=null;const c=(e=>{if(void 0===w){const t=new i((e=unescape(encodeURIComponent(e))).length);for(let n=0;n{if(!Z)return I.importKey(t);try{return await q.importKey("raw",t,n,!1,s)}catch(e){return Z=!1,I.importKey(t)}})(0,c,K,0,N),a=await(async(e,t,n)=>{if(!$)return I.B(t,e.salt,U.iterations,n);try{return await q.deriveBits(e,t,n)}catch(r){return $=!1,I.B(t,e.salt,U.iterations,n)}})(t.assign({salt:o},U),f,8*(2*T[r]+2)),l=new i(a),u=ce(J,ie(l,0,T[r])),h=ce(J,ie(l,T[r],2*T[r])),d=ie(l,2*T[r]);return t.assign(n,{keys:{key:u,$:h,passwordVerification:d},Y:new X(new Q(u),e.from(j)),Z:new Y(h)}),d}function se(e,t){let n=e;return e.length+t.length&&(n=new i(e.length+t.length),n.set(e,0),n.set(t,e.length)),n}function ie(e,t,n){return e.subarray(t,n)}function oe(e,t){return e.m(t)}function ce(e,t){return e.g(t)}class fe extends p{constructor({password:e,passwordVerification:n,checkPasswordOnly:r}){super({start(){t.assign(this,{password:e,passwordVerification:n}),we(this,e)},transform(e,t){const n=this;if(n.password){const t=le(n,e.subarray(0,12));if(n.password=null,t[11]!=n.passwordVerification)throw new s(V);e=e.subarray(12)}r?t.error(new s(R)):t.enqueue(le(n,e))}})}}class ae extends p{constructor({password:e,passwordVerification:n}){super({start(){t.assign(this,{password:e,passwordVerification:n}),we(this,e)},transform(e,t){const n=this;let r,s;if(n.password){n.password=null;const t=B(new i(12));t[11]=n.passwordVerification,r=new i(e.length+t.length),r.set(ue(n,t),0),s=12}else r=new i(e.length),s=0;r.set(ue(n,e),s),t.enqueue(r)}})}}function le(e,t){const n=new i(t.length);for(let r=0;r>>24]),i=~e.te.get(),e.keys=[n,s,i]}function de(e){const t=2|e.keys[2];return pe(r.imul(t,1^t)>>>8)}function pe(e){return 255&e}function ye(e){return 4294967295&e}const me="deflate-raw";class be extends p{constructor(e,{chunkSize:t,CompressionStream:n,CompressionStreamNative:r}){super({});const{compressed:s,encrypted:i,useCompressionStream:o,zipCrypto:c,signed:f,level:a}=e,u=this;let w,h,d=ke(super.readable);i&&!c||!f||([d,w]=d.tee(),w=ze(w,new z)),s&&(d=Se(d,o,{level:a,chunkSize:t},r,n)),i&&(c?d=ze(d,new ae(e)):(h=new te(e),d=ze(d,h))),ve(u,d,(async()=>{let e;i&&!c&&(e=h.signature),i&&!c||!f||(e=await w.getReader().read(),e=new l(e.value.buffer).getUint32(0)),u.signature=e}))}}class ge extends p{constructor(e,{chunkSize:t,DecompressionStream:n,DecompressionStreamNative:r}){super({});const{zipCrypto:i,encrypted:o,signed:c,signature:f,compressed:a,useCompressionStream:u}=e;let w,h,d=ke(super.readable);o&&(i?d=ze(d,new fe(e)):(h=new ee(e),d=ze(d,h))),a&&(d=Se(d,u,{chunkSize:t},r,n)),o&&!i||!c||([d,w]=d.tee(),w=ze(w,new z)),ve(this,d,(async()=>{if((!o||i)&&c){const e=await w.getReader().read(),t=new l(e.value.buffer);if(f!=t.getUint32(0,!1))throw new s(P)}}))}}function ke(e){return ze(e,new p({transform(e,t){e&&e.length&&t.enqueue(e)}}))}function ve(e,n,r){n=ze(n,new p({flush:r})),t.defineProperty(e,"readable",{get:()=>n})}function Se(e,t,n,r,s){try{e=ze(e,new(t&&r?r:s)(me,n))}catch(r){if(!t)throw r;e=ze(e,new s(me,n))}return e}function ze(e,t){return e.pipeThrough(t)}const Ce="data";class xe extends p{constructor(e,n){super({});const r=this,{codecType:s}=e;let i;s.startsWith("deflate")?i=be:s.startsWith("inflate")&&(i=ge);let o=0;const c=new i(e,n),f=super.readable,a=new p({transform(e,t){e&&e.length&&(o+=e.length,t.enqueue(e))},flush(){const{signature:e}=c;t.assign(r,{signature:e,size:o})}});t.defineProperty(r,"readable",{get:()=>f.pipeThrough(c).pipeThrough(a)})}}const _e=new a,Ae=new a;let Ie=0;async function De(e){try{const{options:t,scripts:r,config:s}=e;r&&r.length&&importScripts.apply(void 0,r),self.initCodec&&self.initCodec(),s.CompressionStreamNative=self.CompressionStream,s.DecompressionStreamNative=self.DecompressionStream,self.Deflate&&(s.CompressionStream=new k(self.Deflate)),self.Inflate&&(s.DecompressionStream=new k(self.Inflate));const i={highWaterMark:1,size:()=>s.chunkSize},o=e.readable||new y({async pull(e){const t=new u((e=>_e.set(Ie,e)));Ve({type:"pull",messageId:Ie}),Ie=(Ie+1)%n.MAX_SAFE_INTEGER;const{value:r,done:s}=await t;e.enqueue(r),s&&e.close()}},i),c=e.writable||new m({async write(e){let t;const r=new u((e=>t=e));Ae.set(Ie,t),Ve({type:Ce,value:e,messageId:Ie}),Ie=(Ie+1)%n.MAX_SAFE_INTEGER,await r}},i),f=new xe(t,s);await o.pipeThrough(f).pipeTo(c,{preventClose:!0,preventAbort:!0});try{await c.close()}catch(e){}const{signature:a,size:l}=f;Ve({type:"close",result:{signature:a,size:l}})}catch(e){Pe(e)}}function Ve(e){let{value:t}=e;if(t)if(t.length)try{t=new i(t),e.value=t.buffer,d(e,[e.value])}catch(t){d(e)}else d(e);else d(e)}function Pe(e){const{message:t,stack:n,code:r,name:s}=e;d({error:{message:t,stack:n,code:r,name:s}})}addEventListener("message",(({data:e})=>{const{type:t,messageId:n,value:r,done:s}=e;try{if("start"==t&&De(e),t==Ce){const e=_e.get(n);_e.delete(n),e({value:new i(r),done:s})}if("ack"==t){const e=Ae.get(n);Ae.delete(n),e()}}catch(e){Pe(e)}}));const Re=-2;function Be(t){return Ee(t.map((([t,n])=>new e(t).fill(n,0,t))))}function Ee(t){return t.reduce(((t,n)=>t.concat(e.isArray(n)?Ee(n):n)),[])}const Me=[0,1,2,3].concat(...Be([[2,4],[2,5],[4,6],[4,7],[8,8],[8,9],[16,10],[16,11],[32,12],[32,13],[64,14],[64,15],[2,0],[1,16],[1,17],[2,18],[2,19],[4,20],[4,21],[8,22],[8,23],[16,24],[16,25],[32,26],[32,27],[64,28],[64,29]]));function Ke(){const e=this;function t(e,t){let n=0;do{n|=1&e,e>>>=1,n<<=1}while(--t>0);return n>>>1}e.ne=n=>{const s=e.re,i=e.ie.se,o=e.ie.oe;let c,f,a,l=-1;for(n.ce=0,n.fe=573,c=0;o>c;c++)0!==s[2*c]?(n.ae[++n.ce]=l=c,n.le[c]=0):s[2*c+1]=0;for(;2>n.ce;)a=n.ae[++n.ce]=2>l?++l:0,s[2*a]=1,n.le[a]=0,n.ue--,i&&(n.we-=i[2*a+1]);for(e.he=l,c=r.floor(n.ce/2);c>=1;c--)n.de(s,c);a=o;do{c=n.ae[1],n.ae[1]=n.ae[n.ce--],n.de(s,1),f=n.ae[1],n.ae[--n.fe]=c,n.ae[--n.fe]=f,s[2*a]=s[2*c]+s[2*f],n.le[a]=r.max(n.le[c],n.le[f])+1,s[2*c+1]=s[2*f+1]=a,n.ae[1]=a++,n.de(s,1)}while(n.ce>=2);n.ae[--n.fe]=n.ae[1],(t=>{const n=e.re,r=e.ie.se,s=e.ie.pe,i=e.ie.ye,o=e.ie.me;let c,f,a,l,u,w,h=0;for(l=0;15>=l;l++)t.be[l]=0;for(n[2*t.ae[t.fe]+1]=0,c=t.fe+1;573>c;c++)f=t.ae[c],l=n[2*n[2*f+1]+1]+1,l>o&&(l=o,h++),n[2*f+1]=l,f>e.he||(t.be[l]++,u=0,i>f||(u=s[f-i]),w=n[2*f],t.ue+=w*(l+u),r&&(t.we+=w*(r[2*f+1]+u)));if(0!==h){do{for(l=o-1;0===t.be[l];)l--;t.be[l]--,t.be[l+1]+=2,t.be[o]--,h-=2}while(h>0);for(l=o;0!==l;l--)for(f=t.be[l];0!==f;)a=t.ae[--c],a>e.he||(n[2*a+1]!=l&&(t.ue+=(l-n[2*a+1])*n[2*a],n[2*a+1]=l),f--)}})(n),((e,n,r)=>{const s=[];let i,o,c,f=0;for(i=1;15>=i;i++)s[i]=f=f+r[i-1]<<1;for(o=0;n>=o;o++)c=e[2*o+1],0!==c&&(e[2*o]=t(s[c]++,c))})(s,e.he,n.be)}}function Ue(e,t,n,r,s){const i=this;i.se=e,i.pe=t,i.ye=n,i.oe=r,i.me=s}Ke.ge=[0,1,2,3,4,5,6,7].concat(...Be([[2,8],[2,9],[2,10],[2,11],[4,12],[4,13],[4,14],[4,15],[8,16],[8,17],[8,18],[8,19],[16,20],[16,21],[16,22],[16,23],[32,24],[32,25],[32,26],[31,27],[1,28]])),Ke.ke=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],Ke.ve=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],Ke.Se=e=>256>e?Me[e]:Me[256+(e>>>7)],Ke.ze=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],Ke.Ce=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],Ke.xe=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],Ke._e=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];const Ne=Be([[144,8],[112,9],[24,7],[8,8]]);Ue.Ae=Ee([12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,19,275,147,403,83,339,211,467,51,307,179,435,115,371,243,499,11,267,139,395,75,331,203,459,43,299,171,427,107,363,235,491,27,283,155,411,91,347,219,475,59,315,187,443,123,379,251,507,7,263,135,391,71,327,199,455,39,295,167,423,103,359,231,487,23,279,151,407,87,343,215,471,55,311,183,439,119,375,247,503,15,271,143,399,79,335,207,463,47,303,175,431,111,367,239,495,31,287,159,415,95,351,223,479,63,319,191,447,127,383,255,511,0,64,32,96,16,80,48,112,8,72,40,104,24,88,56,120,4,68,36,100,20,84,52,116,3,131,67,195,35,163,99,227].map(((e,t)=>[e,Ne[t]])));const Oe=Be([[30,5]]);function Te(e,t,n,r,s){const i=this;i.Ie=e,i.De=t,i.Ve=n,i.Pe=r,i.Re=s}Ue.Be=Ee([0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23].map(((e,t)=>[e,Oe[t]]))),Ue.Ee=new Ue(Ue.Ae,Ke.ze,257,286,15),Ue.Me=new Ue(Ue.Be,Ke.Ce,0,30,15),Ue.Ke=new Ue(null,Ke.xe,0,19,7);const We=[new Te(0,0,0,0,0),new Te(4,4,8,4,1),new Te(4,5,16,8,1),new Te(4,6,32,32,1),new Te(4,4,16,16,2),new Te(8,16,32,32,2),new Te(8,16,128,128,2),new Te(8,32,128,256,2),new Te(32,128,258,1024,2),new Te(32,258,258,4096,2)],je=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],He=113,Le=666,Fe=262;function qe(e,t,n,r){const s=e[2*t],i=e[2*n];return i>s||s==i&&r[t]<=r[n]}function Ge(){const e=this;let t,n,s,c,f,a,l,u,w,h,d,p,y,m,b,g,k,v,S,z,C,x,_,A,I,D,V,P,R,B,E,M,K;const U=new Ke,N=new Ke,O=new Ke;let T,W,j,H,L,F;function q(){let t;for(t=0;286>t;t++)E[2*t]=0;for(t=0;30>t;t++)M[2*t]=0;for(t=0;19>t;t++)K[2*t]=0;E[512]=1,e.ue=e.we=0,W=j=0}function G(e,t){let n,r=-1,s=e[1],i=0,o=7,c=4;0===s&&(o=138,c=3),e[2*(t+1)+1]=65535;for(let f=0;t>=f;f++)n=s,s=e[2*(f+1)+1],++ii?K[2*n]+=i:0!==n?(n!=r&&K[2*n]++,K[32]++):i>10?K[36]++:K[34]++,i=0,r=n,0===s?(o=138,c=3):n==s?(o=6,c=3):(o=7,c=4))}function J(t){e.Ue[e.pending++]=t}function Q(e){J(255&e),J(e>>>8&255)}function X(e,t){let n;const r=t;F>16-r?(n=e,L|=n<>>16-F,F+=r-16):(L|=e<=n;n++)if(r=i,i=e[2*(n+1)+1],++o>=c||r!=i){if(f>o)do{Y(r,K)}while(0!=--o);else 0!==r?(r!=s&&(Y(r,K),o--),Y(16,K),X(o-3,2)):o>10?(Y(18,K),X(o-11,7)):(Y(17,K),X(o-3,3));o=0,s=r,0===i?(c=138,f=3):r==i?(c=6,f=3):(c=7,f=4)}}function $(){16==F?(Q(L),L=0,F=0):8>F||(J(255&L),L>>>=8,F-=8)}function ee(t,n){let s,i,o;if(e.Ne[W]=t,e.Oe[W]=255&n,W++,0===t?E[2*n]++:(j++,t--,E[2*(Ke.ge[n]+256+1)]++,M[2*Ke.Se(t)]++),0==(8191&W)&&V>2){for(s=8*W,i=C-k,o=0;30>o;o++)s+=M[2*o]*(5+Ke.Ce[o]);if(s>>>=3,jc);Y(256,t),H=t[513]}function ne(){F>8?Q(L):F>0&&J(255&L),L=0,F=0}function re(t,n,r){X(0+(r?1:0),3),((t,n)=>{ne(),H=8,Q(n),Q(~n),e.Ue.set(u.subarray(t,t+n),e.pending),e.pending+=n})(t,n)}function se(n){((t,n,r)=>{let s,i,o=0;V>0?(U.ne(e),N.ne(e),o=(()=>{let t;for(G(E,U.he),G(M,N.he),O.ne(e),t=18;t>=3&&0===K[2*Ke._e[t]+1];t--);return e.ue+=14+3*(t+1),t})(),s=e.ue+3+7>>>3,i=e.we+3+7>>>3,i>s||(s=i)):s=i=n+5,n+4>s||-1==t?i==s?(X(2+(r?1:0),3),te(Ue.Ae,Ue.Be)):(X(4+(r?1:0),3),((e,t,n)=>{let r;for(X(e-257,5),X(t-1,5),X(n-4,4),r=0;n>r;r++)X(K[2*Ke._e[r]+1],3);Z(E,e-1),Z(M,t-1)})(U.he+1,N.he+1,o+1),te(E,M)):re(t,n,r),q(),r&&ne()})(0>k?-1:k,C-k,n),k=C,t.Te()}function ie(){let e,n,r,s;do{if(s=w-_-C,0===s&&0===C&&0===_)s=f;else if(-1==s)s--;else if(C>=f+f-Fe){u.set(u.subarray(f,f+f),0),x-=f,C-=f,k-=f,e=y,r=e;do{n=65535&d[--r],d[r]=f>n?0:n-f}while(0!=--e);e=f,r=e;do{n=65535&h[--r],h[r]=f>n?0:n-f}while(0!=--e);s+=f}if(0===t.We)return;e=t.je(u,C+_,s),_+=e,3>_||(p=255&u[C],p=(p<_&&0!==t.We)}function oe(e){let t,n,r=I,s=C,i=A;const o=C>f-Fe?C-(f-Fe):0;let c=B;const a=l,w=C+258;let d=u[s+i-1],p=u[s+i];R>A||(r>>=2),c>_&&(c=_);do{if(t=e,u[t+i]==p&&u[t+i-1]==d&&u[t]==u[s]&&u[++t]==u[s+1]){s+=2,t++;do{}while(u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&u[++s]==u[++t]&&w>s);if(n=258-(w-s),s=w-258,n>i){if(x=e,i=n,n>=c)break;d=u[s+i-1],p=u[s+i]}}}while((e=65535&h[e&a])>o&&0!=--r);return i>_?_:i}e.le=[],e.be=[],e.ae=[],E=[],M=[],K=[],e.de=(t,n)=>{const r=e.ae,s=r[n];let i=n<<1;for(;i<=e.ce&&(i(W||(W=8),j||(j=8),G||(G=0),t.Le=null,-1==S&&(S=6),1>j||j>9||8!=W||9>x||x>15||0>S||S>9||0>G||G>2?Re:(t.Fe=e,a=x,f=1<(t.qe=t.Ge=0,t.Le=null,e.pending=0,e.Je=0,n=He,c=0,U.re=E,U.ie=Ue.Ee,N.re=M,N.ie=Ue.Me,O.re=K,O.ie=Ue.Ke,L=0,F=0,H=8,q(),(()=>{w=2*f,d[y-1]=0;for(let e=0;y-1>e;e++)d[e]=0;D=We[V].De,R=We[V].Ie,B=We[V].Ve,I=We[V].Pe,C=0,k=0,_=0,v=A=2,z=0,p=0})(),0))(t))),e.Qe=()=>42!=n&&n!=He&&n!=Le?Re:(e.Oe=null,e.Ne=null,e.Ue=null,d=null,h=null,u=null,e.Fe=null,n==He?-3:0),e.Xe=(e,t,n)=>{let r=0;return-1==t&&(t=6),0>t||t>9||0>n||n>2?Re:(We[V].Re!=We[t].Re&&0!==e.qe&&(r=e.Ye(1)),V!=t&&(V=t,D=We[V].De,R=We[V].Ie,B=We[V].Ve,I=We[V].Pe),P=n,r)},e.Ze=(e,t,r)=>{let s,i=r,o=0;if(!t||42!=n)return Re;if(3>i)return 0;for(i>f-Fe&&(i=f-Fe,o=r-i),u.set(t.subarray(o,o+i),0),C=i,k=i,p=255&u[0],p=(p<=s;s++)p=(p<{let o,w,m,I,R;if(i>4||0>i)return Re;if(!r.$e||!r.et&&0!==r.We||n==Le&&4!=i)return r.Le=je[4],Re;if(0===r.tt)return r.Le=je[7],-5;var B;if(t=r,I=c,c=i,42==n&&(w=8+(a-8<<4)<<8,m=(V-1&255)>>1,m>3&&(m=3),w|=m<<6,0!==C&&(w|=32),w+=31-w%31,n=He,J((B=w)>>8&255),J(255&B)),0!==e.pending){if(t.Te(),0===t.tt)return c=-1,0}else if(0===t.We&&I>=i&&4!=i)return t.Le=je[7],-5;if(n==Le&&0!==t.We)return r.Le=je[7],-5;if(0!==t.We||0!==_||0!=i&&n!=Le){switch(R=-1,We[V].Re){case 0:R=(e=>{let n,r=65535;for(r>s-5&&(r=s-5);;){if(1>=_){if(ie(),0===_&&0==e)return 0;if(0===_)break}if(C+=_,_=0,n=k+r,(0===C||C>=n)&&(_=C-n,C=n,se(!1),0===t.tt))return 0;if(C-k>=f-Fe&&(se(!1),0===t.tt))return 0}return se(4==e),0===t.tt?4==e?2:0:4==e?3:1})(i);break;case 1:R=(e=>{let n,r=0;for(;;){if(Fe>_){if(ie(),Fe>_&&0==e)return 0;if(0===_)break}if(3>_||(p=(p<f-Fe||2!=P&&(v=oe(r)),3>v)n=ee(0,255&u[C]),_--,C++;else if(n=ee(C-x,v-3),_-=v,v>D||3>_)C+=v,v=0,p=255&u[C],p=(p<{let n,r,s=0;for(;;){if(Fe>_){if(ie(),Fe>_&&0==e)return 0;if(0===_)break}if(3>_||(p=(p<A&&f-Fe>=(C-s&65535)&&(2!=P&&(v=oe(s)),5>=v&&(1==P||3==v&&C-x>4096)&&(v=2)),3>A||v>A)if(0!==z){if(n=ee(0,255&u[C-1]),n&&se(!1),C++,_--,0===t.tt)return 0}else z=1,C++,_--;else{r=C+_-3,n=ee(C-1-S,A-3),_-=A-1,A-=2;do{++C>r||(p=(p<1+H+10-F&&(X(2,3),Y(256,Ue.Ae),$()),H=7;else if(re(0,0,!1),3==i)for(o=0;y>o;o++)d[o]=0;if(t.Te(),0===t.tt)return c=-1,0}}return 4!=i?0:1}}function Je(){const e=this;e.nt=0,e.rt=0,e.We=0,e.qe=0,e.tt=0,e.Ge=0}function Qe(e){const t=new Je,n=(o=e&&e.chunkSize?e.chunkSize:65536)+5*(r.floor(o/16383)+1);var o;const c=new i(n);let f=e?e.level:-1;void 0===f&&(f=-1),t.He(f),t.$e=c,this.append=(e,r)=>{let o,f,a=0,l=0,u=0;const w=[];if(e.length){t.nt=0,t.et=e,t.We=e.length;do{if(t.rt=0,t.tt=n,o=t.Ye(0),0!=o)throw new s("deflating: "+t.Le);t.rt&&(t.rt==n?w.push(new i(c)):w.push(c.slice(0,t.rt))),u+=t.rt,r&&t.nt>0&&t.nt!=a&&(r(t.nt),a=t.nt)}while(t.We>0||0===t.tt);return w.length>1?(f=new i(u),w.forEach((e=>{f.set(e,l),l+=e.length}))):f=w[0]||new i,f}},this.flush=()=>{let e,r,o=0,f=0;const a=[];do{if(t.rt=0,t.tt=n,e=t.Ye(4),1!=e&&0!=e)throw new s("deflating: "+t.Le);n-t.tt>0&&a.push(c.slice(0,t.rt)),f+=t.rt}while(t.We>0||0===t.tt);return t.Qe(),r=new i(f),a.forEach((e=>{r.set(e,o),o+=e.length})),r}}Je.prototype={He(e,t){const n=this;return n.Fe=new Ge,t||(t=15),n.Fe.He(n,e,t)},Ye(e){const t=this;return t.Fe?t.Fe.Ye(t,e):Re},Qe(){const e=this;if(!e.Fe)return Re;const t=e.Fe.Qe();return e.Fe=null,t},Xe(e,t){const n=this;return n.Fe?n.Fe.Xe(n,e,t):Re},Ze(e,t){const n=this;return n.Fe?n.Fe.Ze(n,e,t):Re},je(e,t,n){const r=this;let s=r.We;return s>n&&(s=n),0===s?0:(r.We-=s,e.set(r.et.subarray(r.nt,r.nt+s),t),r.nt+=s,r.qe+=s,s)},Te(){const e=this;let t=e.Fe.pending;t>e.tt&&(t=e.tt),0!==t&&(e.$e.set(e.Fe.Ue.subarray(e.Fe.Je,e.Fe.Je+t),e.rt),e.rt+=t,e.Fe.Je+=t,e.Ge+=t,e.tt-=t,e.Fe.pending-=t,0===e.Fe.pending&&(e.Fe.Je=0))}};const Xe=-2,Ye=-3,Ze=-5,$e=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],et=[96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,192,80,7,10,0,8,96,0,8,32,0,9,160,0,8,0,0,8,128,0,8,64,0,9,224,80,7,6,0,8,88,0,8,24,0,9,144,83,7,59,0,8,120,0,8,56,0,9,208,81,7,17,0,8,104,0,8,40,0,9,176,0,8,8,0,8,136,0,8,72,0,9,240,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,200,81,7,13,0,8,100,0,8,36,0,9,168,0,8,4,0,8,132,0,8,68,0,9,232,80,7,8,0,8,92,0,8,28,0,9,152,84,7,83,0,8,124,0,8,60,0,9,216,82,7,23,0,8,108,0,8,44,0,9,184,0,8,12,0,8,140,0,8,76,0,9,248,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,196,81,7,11,0,8,98,0,8,34,0,9,164,0,8,2,0,8,130,0,8,66,0,9,228,80,7,7,0,8,90,0,8,26,0,9,148,84,7,67,0,8,122,0,8,58,0,9,212,82,7,19,0,8,106,0,8,42,0,9,180,0,8,10,0,8,138,0,8,74,0,9,244,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,204,81,7,15,0,8,102,0,8,38,0,9,172,0,8,6,0,8,134,0,8,70,0,9,236,80,7,9,0,8,94,0,8,30,0,9,156,84,7,99,0,8,126,0,8,62,0,9,220,82,7,27,0,8,110,0,8,46,0,9,188,0,8,14,0,8,142,0,8,78,0,9,252,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,194,80,7,10,0,8,97,0,8,33,0,9,162,0,8,1,0,8,129,0,8,65,0,9,226,80,7,6,0,8,89,0,8,25,0,9,146,83,7,59,0,8,121,0,8,57,0,9,210,81,7,17,0,8,105,0,8,41,0,9,178,0,8,9,0,8,137,0,8,73,0,9,242,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,202,81,7,13,0,8,101,0,8,37,0,9,170,0,8,5,0,8,133,0,8,69,0,9,234,80,7,8,0,8,93,0,8,29,0,9,154,84,7,83,0,8,125,0,8,61,0,9,218,82,7,23,0,8,109,0,8,45,0,9,186,0,8,13,0,8,141,0,8,77,0,9,250,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,198,81,7,11,0,8,99,0,8,35,0,9,166,0,8,3,0,8,131,0,8,67,0,9,230,80,7,7,0,8,91,0,8,27,0,9,150,84,7,67,0,8,123,0,8,59,0,9,214,82,7,19,0,8,107,0,8,43,0,9,182,0,8,11,0,8,139,0,8,75,0,9,246,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,206,81,7,15,0,8,103,0,8,39,0,9,174,0,8,7,0,8,135,0,8,71,0,9,238,80,7,9,0,8,95,0,8,31,0,9,158,84,7,99,0,8,127,0,8,63,0,9,222,82,7,27,0,8,111,0,8,47,0,9,190,0,8,15,0,8,143,0,8,79,0,9,254,96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,193,80,7,10,0,8,96,0,8,32,0,9,161,0,8,0,0,8,128,0,8,64,0,9,225,80,7,6,0,8,88,0,8,24,0,9,145,83,7,59,0,8,120,0,8,56,0,9,209,81,7,17,0,8,104,0,8,40,0,9,177,0,8,8,0,8,136,0,8,72,0,9,241,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,201,81,7,13,0,8,100,0,8,36,0,9,169,0,8,4,0,8,132,0,8,68,0,9,233,80,7,8,0,8,92,0,8,28,0,9,153,84,7,83,0,8,124,0,8,60,0,9,217,82,7,23,0,8,108,0,8,44,0,9,185,0,8,12,0,8,140,0,8,76,0,9,249,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,197,81,7,11,0,8,98,0,8,34,0,9,165,0,8,2,0,8,130,0,8,66,0,9,229,80,7,7,0,8,90,0,8,26,0,9,149,84,7,67,0,8,122,0,8,58,0,9,213,82,7,19,0,8,106,0,8,42,0,9,181,0,8,10,0,8,138,0,8,74,0,9,245,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,205,81,7,15,0,8,102,0,8,38,0,9,173,0,8,6,0,8,134,0,8,70,0,9,237,80,7,9,0,8,94,0,8,30,0,9,157,84,7,99,0,8,126,0,8,62,0,9,221,82,7,27,0,8,110,0,8,46,0,9,189,0,8,14,0,8,142,0,8,78,0,9,253,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,195,80,7,10,0,8,97,0,8,33,0,9,163,0,8,1,0,8,129,0,8,65,0,9,227,80,7,6,0,8,89,0,8,25,0,9,147,83,7,59,0,8,121,0,8,57,0,9,211,81,7,17,0,8,105,0,8,41,0,9,179,0,8,9,0,8,137,0,8,73,0,9,243,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,203,81,7,13,0,8,101,0,8,37,0,9,171,0,8,5,0,8,133,0,8,69,0,9,235,80,7,8,0,8,93,0,8,29,0,9,155,84,7,83,0,8,125,0,8,61,0,9,219,82,7,23,0,8,109,0,8,45,0,9,187,0,8,13,0,8,141,0,8,77,0,9,251,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,199,81,7,11,0,8,99,0,8,35,0,9,167,0,8,3,0,8,131,0,8,67,0,9,231,80,7,7,0,8,91,0,8,27,0,9,151,84,7,67,0,8,123,0,8,59,0,9,215,82,7,19,0,8,107,0,8,43,0,9,183,0,8,11,0,8,139,0,8,75,0,9,247,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,207,81,7,15,0,8,103,0,8,39,0,9,175,0,8,7,0,8,135,0,8,71,0,9,239,80,7,9,0,8,95,0,8,31,0,9,159,84,7,99,0,8,127,0,8,63,0,9,223,82,7,27,0,8,111,0,8,47,0,9,191,0,8,15,0,8,143,0,8,79,0,9,255],tt=[80,5,1,87,5,257,83,5,17,91,5,4097,81,5,5,89,5,1025,85,5,65,93,5,16385,80,5,3,88,5,513,84,5,33,92,5,8193,82,5,9,90,5,2049,86,5,129,192,5,24577,80,5,2,87,5,385,83,5,25,91,5,6145,81,5,7,89,5,1537,85,5,97,93,5,24577,80,5,4,88,5,769,84,5,49,92,5,12289,82,5,13,90,5,3073,86,5,193,192,5,24577],nt=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],rt=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,112,112],st=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],it=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];function ot(){let e,t,n,r,s,i;function o(e,t,o,c,f,a,l,u,w,h,d){let p,y,m,b,g,k,v,S,z,C,x,_,A,I,D;C=0,g=o;do{n[e[t+C]]++,C++,g--}while(0!==g);if(n[0]==o)return l[0]=-1,u[0]=0,0;for(S=u[0],k=1;15>=k&&0===n[k];k++);for(v=k,k>S&&(S=k),g=15;0!==g&&0===n[g];g--);for(m=g,S>g&&(S=g),u[0]=S,I=1<k;k++,I<<=1)if(0>(I-=n[k]))return Ye;if(0>(I-=n[g]))return Ye;for(n[g]+=I,i[1]=k=0,C=1,A=2;0!=--g;)i[A]=k+=n[C],A++,C++;g=0,C=0;do{0!==(k=e[t+C])&&(d[i[k]++]=g),C++}while(++g=v;v++)for(p=n[v];0!=p--;){for(;v>_+S;){if(b++,_+=S,D=m-_,D=D>S?S:D,(y=1<<(k=v-_))>p+1&&(y-=p+1,A=v,D>k))for(;++kn[++A];)y-=n[A];if(D=1<1440)return Ye;s[b]=x=h[0],h[0]+=D,0!==b?(i[b]=g,r[0]=k,r[1]=S,k=g>>>_-S,r[2]=x-s[b-1]-k,w.set(r,3*(s[b-1]+k))):l[0]=x}for(r[1]=v-_,o>C?d[C]d[C]?0:96,r[2]=d[C++]):(r[0]=a[d[C]-c]+16+64,r[2]=f[d[C++]-c]):r[0]=192,y=1<>>_;D>k;k+=y)w.set(r,3*(x+k));for(k=1<>>=1)g^=k;for(g^=k,z=(1<<_)-1;(g&z)!=i[b];)b--,_-=S,z=(1<<_)-1}return 0!==I&&1!=m?Ze:0}function c(o){let c;for(e||(e=[],t=[],n=new f(16),r=[],s=new f(15),i=new f(16)),t.lengthc;c++)t[c]=0;for(c=0;16>c;c++)n[c]=0;for(c=0;3>c;c++)r[c]=0;s.set(n.subarray(0,15),0),i.set(n.subarray(0,16),0)}this.st=(n,r,s,i,f)=>{let a;return c(19),e[0]=0,a=o(n,0,19,19,null,null,s,r,i,e,t),a==Ye?f.Le="oversubscribed dynamic bit lengths tree":a!=Ze&&0!==r[0]||(f.Le="incomplete dynamic bit lengths tree",a=Ye),a},this.it=(n,r,s,i,f,a,l,u,w)=>{let h;return c(288),e[0]=0,h=o(s,0,n,257,nt,rt,a,i,u,e,t),0!=h||0===i[0]?(h==Ye?w.Le="oversubscribed literal/length tree":-4!=h&&(w.Le="incomplete literal/length tree",h=Ye),h):(c(288),h=o(s,n,r,0,st,it,l,f,u,e,t),0!=h||0===f[0]&&n>257?(h==Ye?w.Le="oversubscribed distance tree":h==Ze?(w.Le="incomplete distance tree",h=Ye):-4!=h&&(w.Le="empty distance tree with lengths",h=Ye),h):0)}}function ct(){const e=this;let t,n,r,s,i=0,o=0,c=0,f=0,a=0,l=0,u=0,w=0,h=0,d=0;function p(e,t,n,r,s,i,o,c){let f,a,l,u,w,h,d,p,y,m,b,g,k,v,S,z;d=c.nt,p=c.We,w=o.ot,h=o.ct,y=o.write,m=yh;)p--,w|=(255&c.ft(d++))<>=a[z+1],h-=a[z+1],0!=(16&u)){for(u&=15,k=a[z+2]+(w&$e[u]),w>>=u,h-=u;15>h;)p--,w|=(255&c.ft(d++))<>=a[z+1],h-=a[z+1],0!=(16&u)){for(u&=15;u>h;)p--,w|=(255&c.ft(d++))<>=u,h-=u,m-=k,v>y){S=y-v;do{S+=o.end}while(0>S);if(u=o.end-S,k>u){if(k-=u,y-S>0&&u>y-S)do{o.lt[y++]=o.lt[S++]}while(0!=--u);else o.lt.set(o.lt.subarray(S,S+u),y),y+=u,S+=u,u=0;S=0}}else S=y-v,y-S>0&&2>y-S?(o.lt[y++]=o.lt[S++],o.lt[y++]=o.lt[S++],k-=2):(o.lt.set(o.lt.subarray(S,S+2),y),y+=2,S+=2,k-=2);if(y-S>0&&k>y-S)do{o.lt[y++]=o.lt[S++]}while(0!=--k);else o.lt.set(o.lt.subarray(S,S+k),y),y+=k,S+=k,k=0;break}if(0!=(64&u))return c.Le="invalid distance code",k=c.We-p,k=k>h>>3?h>>3:k,p+=k,d-=k,h-=k<<3,o.ot=w,o.ct=h,c.We=p,c.qe+=d-c.nt,c.nt=d,o.write=y,Ye;f+=a[z+2],f+=w&$e[u],z=3*(l+f),u=a[z]}break}if(0!=(64&u))return 0!=(32&u)?(k=c.We-p,k=k>h>>3?h>>3:k,p+=k,d-=k,h-=k<<3,o.ot=w,o.ct=h,c.We=p,c.qe+=d-c.nt,c.nt=d,o.write=y,1):(c.Le="invalid literal/length code",k=c.We-p,k=k>h>>3?h>>3:k,p+=k,d-=k,h-=k<<3,o.ot=w,o.ct=h,c.We=p,c.qe+=d-c.nt,c.nt=d,o.write=y,Ye);if(f+=a[z+2],f+=w&$e[u],z=3*(l+f),0===(u=a[z])){w>>=a[z+1],h-=a[z+1],o.lt[y++]=a[z+2],m--;break}}else w>>=a[z+1],h-=a[z+1],o.lt[y++]=a[z+2],m--}while(m>=258&&p>=10);return k=c.We-p,k=k>h>>3?h>>3:k,p+=k,d-=k,h-=k<<3,o.ot=w,o.ct=h,c.We=p,c.qe+=d-c.nt,c.nt=d,o.write=y,0}e.init=(e,i,o,c,f,a)=>{t=0,u=e,w=i,r=o,h=c,s=f,d=a,n=null},e.ut=(e,y,m)=>{let b,g,k,v,S,z,C,x=0,_=0,A=0;for(A=y.nt,v=y.We,x=e.ot,_=e.ct,S=e.write,z=S=258&&v>=10&&(e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,m=p(u,w,r,h,s,d,e,y),A=y.nt,v=y.We,x=e.ot,_=e.ct,S=e.write,z=S_;){if(0===v)return e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);m=0,v--,x|=(255&y.ft(A++))<<_,_+=8}if(g=3*(o+(x&$e[b])),x>>>=n[g+1],_-=n[g+1],k=n[g],0===k){f=n[g+2],t=6;break}if(0!=(16&k)){a=15&k,i=n[g+2],t=2;break}if(0==(64&k)){c=k,o=g/3+n[g+2];break}if(0!=(32&k)){t=7;break}return t=9,y.Le="invalid literal/length code",m=Ye,e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);case 2:for(b=a;b>_;){if(0===v)return e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);m=0,v--,x|=(255&y.ft(A++))<<_,_+=8}i+=x&$e[b],x>>=b,_-=b,c=w,n=s,o=d,t=3;case 3:for(b=c;b>_;){if(0===v)return e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);m=0,v--,x|=(255&y.ft(A++))<<_,_+=8}if(g=3*(o+(x&$e[b])),x>>=n[g+1],_-=n[g+1],k=n[g],0!=(16&k)){a=15&k,l=n[g+2],t=4;break}if(0==(64&k)){c=k,o=g/3+n[g+2];break}return t=9,y.Le="invalid distance code",m=Ye,e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);case 4:for(b=a;b>_;){if(0===v)return e.ot=x,e.ct=_,y.We=v,y.qe+=A-y.nt,y.nt=A,e.write=S,e.wt(y,m);m=0,v--,x|=(255&y.ft(A++))<<_,_+=8}l+=x&$e[b],x>>=b,_-=b,t=5;case 5:for(C=S-l;0>C;)C+=e.end;for(;0!==i;){if(0===z&&(S==e.end&&0!==e.read&&(S=0,z=S7&&(_-=8,v++,A--),e.write=S,m=e.wt(y,m),S=e.write,z=S{}}ot.dt=(e,t,n,r)=>(e[0]=9,t[0]=5,n[0]=et,r[0]=tt,0);const ft=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];function at(e,t){const n=this;let r,s=0,o=0,c=0,a=0;const l=[0],u=[0],w=new ct;let h=0,d=new f(4320);const p=new ot;n.ct=0,n.ot=0,n.lt=new i(t),n.end=t,n.read=0,n.write=0,n.reset=(e,t)=>{t&&(t[0]=0),6==s&&w.ht(e),s=0,n.ct=0,n.ot=0,n.read=n.write=0},n.reset(e,null),n.wt=(e,t)=>{let r,s,i;return s=e.rt,i=n.read,r=(i>n.write?n.end:n.write)-i,r>e.tt&&(r=e.tt),0!==r&&t==Ze&&(t=0),e.tt-=r,e.Ge+=r,e.$e.set(n.lt.subarray(i,i+r),s),s+=r,i+=r,i==n.end&&(i=0,n.write==n.end&&(n.write=0),r=n.write-i,r>e.tt&&(r=e.tt),0!==r&&t==Ze&&(t=0),e.tt-=r,e.Ge+=r,e.$e.set(n.lt.subarray(i,i+r),s),s+=r,i+=r),e.rt=s,n.read=i,t},n.ut=(e,t)=>{let i,f,y,m,b,g,k,v;for(m=e.nt,b=e.We,f=n.ot,y=n.ct,g=n.write,k=gy;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<>>1){case 0:f>>>=3,y-=3,i=7&y,f>>>=i,y-=i,s=1;break;case 1:S=[],z=[],C=[[]],x=[[]],ot.dt(S,z,C,x),w.init(S[0],z[0],C[0],0,x[0],0),f>>>=3,y-=3,s=6;break;case 2:f>>>=3,y-=3,s=3;break;case 3:return f>>>=3,y-=3,s=9,e.Le="invalid block type",t=Ye,n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t)}break;case 1:for(;32>y;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<>>16&65535)!=(65535&f))return s=9,e.Le="invalid stored block lengths",t=Ye,n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);o=65535&f,f=y=0,s=0!==o?2:0!==h?7:0;break;case 2:if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);if(0===k&&(g==n.end&&0!==n.read&&(g=0,k=gb&&(i=b),i>k&&(i=k),n.lt.set(e.je(m,i),g),m+=i,b-=i,g+=i,k-=i,0!=(o-=i))break;s=0!==h?7:0;break;case 3:for(;14>y;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<29||(i>>5&31)>29)return s=9,e.Le="too many length or distance symbols",t=Ye,n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);if(i=258+(31&i)+(i>>5&31),!r||r.lengthv;v++)r[v]=0;f>>>=14,y-=14,a=0,s=4;case 4:for(;4+(c>>>10)>a;){for(;3>y;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<>>=3,y-=3}for(;19>a;)r[ft[a++]]=0;if(l[0]=7,i=p.st(r,l,u,d,e),0!=i)return(t=i)==Ye&&(r=null,s=9),n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);a=0,s=5;case 5:for(;i=c,258+(31&i)+(i>>5&31)>a;){let o,w;for(i=l[0];i>y;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<w)f>>>=i,y-=i,r[a++]=w;else{for(v=18==w?7:w-14,o=18==w?11:3;i+v>y;){if(0===b)return n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);t=0,b--,f|=(255&e.ft(m++))<>>=i,y-=i,o+=f&$e[v],f>>>=v,y-=v,v=a,i=c,v+o>258+(31&i)+(i>>5&31)||16==w&&1>v)return r=null,s=9,e.Le="invalid bit length repeat",t=Ye,n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);w=16==w?r[v-1]:0;do{r[v++]=w}while(0!=--o);a=v}}if(u[0]=-1,_=[],A=[],I=[],D=[],_[0]=9,A[0]=6,i=c,i=p.it(257+(31&i),1+(i>>5&31),r,_,A,I,D,d,e),0!=i)return i==Ye&&(r=null,s=9),t=i,n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,n.wt(e,t);w.init(_[0],A[0],d,I[0],d,D[0]),s=6;case 6:if(n.ot=f,n.ct=y,e.We=b,e.qe+=m-e.nt,e.nt=m,n.write=g,1!=(t=w.ut(n,e,t)))return n.wt(e,t);if(t=0,w.ht(e),m=e.nt,b=e.We,f=n.ot,y=n.ct,g=n.write,k=g{n.reset(e,null),n.lt=null,d=null},n.yt=(e,t,r)=>{n.lt.set(e.subarray(t,t+r),0),n.read=n.write=r},n.bt=()=>1==s?1:0}const lt=13,ut=[0,0,255,255];function wt(){const e=this;function t(e){return e&&e.gt?(e.qe=e.Ge=0,e.Le=null,e.gt.mode=7,e.gt.kt.reset(e,null),0):Xe}e.mode=0,e.method=0,e.vt=[0],e.St=0,e.marker=0,e.zt=0,e.Ct=t=>(e.kt&&e.kt.ht(t),e.kt=null,0),e.xt=(n,r)=>(n.Le=null,e.kt=null,8>r||r>15?(e.Ct(n),Xe):(e.zt=r,n.gt.kt=new at(n,1<{let n,r;if(!e||!e.gt||!e.et)return Xe;const s=e.gt;for(t=4==t?Ze:0,n=Ze;;)switch(s.mode){case 0:if(0===e.We)return n;if(n=t,e.We--,e.qe++,8!=(15&(s.method=e.ft(e.nt++)))){s.mode=lt,e.Le="unknown compression method",s.marker=5;break}if(8+(s.method>>4)>s.zt){s.mode=lt,e.Le="invalid win size",s.marker=5;break}s.mode=1;case 1:if(0===e.We)return n;if(n=t,e.We--,e.qe++,r=255&e.ft(e.nt++),((s.method<<8)+r)%31!=0){s.mode=lt,e.Le="incorrect header check",s.marker=5;break}if(0==(32&r)){s.mode=7;break}s.mode=2;case 2:if(0===e.We)return n;n=t,e.We--,e.qe++,s.St=(255&e.ft(e.nt++))<<24&4278190080,s.mode=3;case 3:if(0===e.We)return n;n=t,e.We--,e.qe++,s.St+=(255&e.ft(e.nt++))<<16&16711680,s.mode=4;case 4:if(0===e.We)return n;n=t,e.We--,e.qe++,s.St+=(255&e.ft(e.nt++))<<8&65280,s.mode=5;case 5:return 0===e.We?n:(n=t,e.We--,e.qe++,s.St+=255&e.ft(e.nt++),s.mode=6,2);case 6:return s.mode=lt,e.Le="need dictionary",s.marker=0,Xe;case 7:if(n=s.kt.ut(e,n),n==Ye){s.mode=lt,s.marker=0;break}if(0==n&&(n=t),1!=n)return n;n=t,s.kt.reset(e,s.vt),s.mode=12;case 12:return e.We=0,1;case lt:return Ye;default:return Xe}},e.At=(e,t,n)=>{let r=0,s=n;if(!e||!e.gt||6!=e.gt.mode)return Xe;const i=e.gt;return s<1<{let n,r,s,i,o;if(!e||!e.gt)return Xe;const c=e.gt;if(c.mode!=lt&&(c.mode=lt,c.marker=0),0===(n=e.We))return Ze;for(r=e.nt,s=c.marker;0!==n&&4>s;)e.ft(r)==ut[s]?s++:s=0!==e.ft(r)?0:4-s,r++,n--;return e.qe+=r-e.nt,e.nt=r,e.We=n,c.marker=s,4!=s?Ye:(i=e.qe,o=e.Ge,t(e),e.qe=i,e.Ge=o,c.mode=7,0)},e.Dt=e=>e&&e.gt&&e.gt.kt?e.gt.kt.bt():Xe}function ht(){}function dt(e){const t=new ht,n=e&&e.chunkSize?r.floor(2*e.chunkSize):131072,o=new i(n);let c=!1;t.xt(),t.$e=o,this.append=(e,r)=>{const f=[];let a,l,u=0,w=0,h=0;if(0!==e.length){t.nt=0,t.et=e,t.We=e.length;do{if(t.rt=0,t.tt=n,0!==t.We||c||(t.nt=0,c=!0),a=t._t(0),c&&a===Ze){if(0!==t.We)throw new s("inflating: bad input")}else if(0!==a&&1!==a)throw new s("inflating: "+t.Le);if((c||1===a)&&t.We===e.length)throw new s("inflating: bad input");t.rt&&(t.rt===n?f.push(new i(o)):f.push(o.slice(0,t.rt))),h+=t.rt,r&&t.nt>0&&t.nt!=u&&(r(t.nt),u=t.nt)}while(t.We>0||0===t.tt);return f.length>1?(l=new i(h),f.forEach((e=>{l.set(e,w),w+=e.length}))):l=f[0]||new i,l}},this.flush=()=>{t.Ct()}}ht.prototype={xt(e){const t=this;return t.gt=new wt,e||(e=15),t.gt.xt(t,e)},_t(e){const t=this;return t.gt?t.gt._t(t,e):Xe},Ct(){const e=this;if(!e.gt)return Xe;const t=e.gt.Ct(e);return e.gt=null,t},It(){const e=this;return e.gt?e.gt.It(e):Xe},At(e,t){const n=this;return n.gt?n.gt.At(n,e,t):Xe},ft(e){return this.et[e]},je(e,t){return this.et.subarray(e,e+t)}},self.initCodec=()=>{self.Deflate=Qe,self.Inflate=dt};\n'],{type:"text/javascript"}));e({workerScripts:{inflate:[t],deflate:[t]}});} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon"; -const HTTP_HEADER_CONTENT_TYPE = "Content-Type"; -const DEFAULT_CHUNK_SIZE = 64 * 1024; - -const PROPERTY_NAME_WRITABLE = "writable"; - -class Stream { - - constructor() { - this.size = 0; - } - - init() { - this.initialized = true; - } -} - -class Reader extends Stream { - - get readable() { - const reader = this; - const { chunkSize = DEFAULT_CHUNK_SIZE } = reader; - const readable = new ReadableStream({ - start() { - this.chunkOffset = 0; - }, - async pull(controller) { - const { offset = 0, size, diskNumberStart } = readable; - const { chunkOffset } = this; - controller.enqueue(await readUint8Array(reader, offset + chunkOffset, Math.min(chunkSize, size - chunkOffset), diskNumberStart)); - if (chunkOffset + chunkSize > size) { - controller.close(); - } else { - this.chunkOffset += chunkSize; - } - } - }); - return readable; - } -} - -class BlobReader extends Reader { - - constructor(blob) { - super(); - Object.assign(this, { - blob, - size: blob.size - }); - } - - async readUint8Array(offset, length) { - const reader = this; - const offsetEnd = offset + length; - const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob; - return new Uint8Array(await blob.arrayBuffer()); - } -} - -class BlobWriter extends Stream { - - constructor(contentType) { - super(); - const writer = this; - const transformStream = new TransformStream(); - const headers = []; - if (contentType) { - headers.push([HTTP_HEADER_CONTENT_TYPE, contentType]); - } - Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, { - get() { - return transformStream.writable; - } - }); - writer.blob = new Response(transformStream.readable, { headers }).blob(); - } - - getData() { - return this.blob; - } -} - -class TextWriter extends BlobWriter { - - constructor(encoding) { - super(encoding); - Object.assign(this, { - encoding, - utf8: !encoding || encoding.toLowerCase() == "utf-8" - }); - } - - async getData() { - const { - encoding, - utf8 - } = this; - const blob = await super.getData(); - if (blob.text && utf8) { - return blob.text(); - } else { - const reader = new FileReader(); - return new Promise((resolve, reject) => { - Object.assign(reader, { - onload: ({ target }) => resolve(target.result), - onerror: () => reject(reader.error) - }); - reader.readAsText(blob, encoding); - }); - } - } -} - -class SplitDataReader extends Reader { - - constructor(readers) { - super(); - this.readers = readers; - } - - async init() { - const reader = this; - const { readers } = reader; - reader.lastDiskNumber = 0; - await Promise.all(readers.map(async diskReader => { - await diskReader.init(); - reader.size += diskReader.size; - })); - super.init(); - } - - async readUint8Array(offset, length, diskNumber = 0) { - const reader = this; - const { readers } = this; - let result; - let currentDiskNumber = diskNumber; - if (currentDiskNumber == -1) { - currentDiskNumber = readers.length - 1; - } - let currentReaderOffset = offset; - while (currentReaderOffset >= readers[currentDiskNumber].size) { - currentReaderOffset -= readers[currentDiskNumber].size; - currentDiskNumber++; - } - const currentReader = readers[currentDiskNumber]; - const currentReaderSize = currentReader.size; - if (currentReaderOffset + length <= currentReaderSize) { - result = await readUint8Array(currentReader, currentReaderOffset, length); - } else { - const chunkLength = currentReaderSize - currentReaderOffset; - result = new Uint8Array(length); - result.set(await readUint8Array(currentReader, currentReaderOffset, chunkLength)); - result.set(await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber), chunkLength); - } - reader.lastDiskNumber = Math.max(currentDiskNumber, reader.lastDiskNumber); - return result; - } -} - -class SplitDataWriter extends Stream { - - constructor(writerGenerator, maxSize = 4294967295) { - super(); - const zipWriter = this; - Object.assign(zipWriter, { - diskNumber: 0, - diskOffset: 0, - size: 0, - maxSize, - availableSize: maxSize - }); - let diskSourceWriter, diskWritable, diskWriter; - const writable = new WritableStream({ - async write(chunk) { - const { availableSize } = zipWriter; - if (!diskWriter) { - const { value, done } = await writerGenerator.next(); - if (done && !value) { - throw new Error(ERR_ITERATOR_COMPLETED_TOO_SOON); - } else { - diskSourceWriter = value; - diskSourceWriter.size = 0; - if (diskSourceWriter.maxSize) { - zipWriter.maxSize = diskSourceWriter.maxSize; - } - zipWriter.availableSize = zipWriter.maxSize; - await initStream(diskSourceWriter); - diskWritable = value.writable; - diskWriter = diskWritable.getWriter(); - } - await this.write(chunk); - } else if (chunk.length >= availableSize) { - await writeChunk(chunk.slice(0, availableSize)); - await closeDisk(); - zipWriter.diskOffset += diskSourceWriter.size; - zipWriter.diskNumber++; - diskWriter = null; - await this.write(chunk.slice(availableSize)); - } else { - await writeChunk(chunk); - } - }, - async close() { - await diskWriter.ready; - await closeDisk(); - } - }); - Object.defineProperty(zipWriter, PROPERTY_NAME_WRITABLE, { - get() { - return writable; - } - }); - - async function writeChunk(chunk) { - const chunkLength = chunk.length; - if (chunkLength) { - await diskWriter.ready; - await diskWriter.write(chunk); - diskSourceWriter.size += chunkLength; - zipWriter.size += chunkLength; - zipWriter.availableSize -= chunkLength; - } - } - - async function closeDisk() { - diskWritable.size = diskSourceWriter.size; - await diskWriter.close(); - } - } -} - -async function initStream(stream, initSize) { - if (stream.init && !stream.initialized) { - await stream.init(initSize); - } -} - -function initReader(reader) { - if (Array.isArray(reader)) { - reader = new SplitDataReader(reader); - } - if (reader instanceof ReadableStream) { - reader = { - readable: reader - }; - } - return reader; -} - -function initWriter(writer) { - if (writer.writable === UNDEFINED_VALUE && typeof writer.next == FUNCTION_TYPE$1) { - writer = new SplitDataWriter(writer); - } - if (writer instanceof WritableStream) { - writer = { - writable: writer - }; - } - const { writable } = writer; - if (writable.size === UNDEFINED_VALUE) { - writable.size = 0; - } - const splitZipFile = writer instanceof SplitDataWriter; - if (!splitZipFile) { - Object.assign(writer, { - diskNumber: 0, - diskOffset: 0, - availableSize: Infinity, - maxSize: Infinity - }); - } - return writer; -} - -function readUint8Array(reader, offset, size, diskNumber) { - return reader.readUint8Array(offset, size, diskNumber); -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* global TextDecoder */ - -const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split(""); -const VALID_CP437 = CP437.length == 256; - -function decodeCP437(stringValue) { - if (VALID_CP437) { - let result = ""; - for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) { - result += CP437[stringValue[indexCharacter]]; - } - return result; - } else { - return new TextDecoder().decode(stringValue); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -function decodeText(value, encoding) { - if (encoding && encoding.trim().toLowerCase() == "cp437") { - return decodeCP437(value); - } else { - return new TextDecoder(encoding).decode(value); - } -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const PROPERTY_NAME_FILENAME = "filename"; -const PROPERTY_NAME_RAW_FILENAME = "rawFilename"; -const PROPERTY_NAME_COMMENT = "comment"; -const PROPERTY_NAME_RAW_COMMENT = "rawComment"; -const PROPERTY_NAME_UNCOMPPRESSED_SIZE = "uncompressedSize"; -const PROPERTY_NAME_COMPPRESSED_SIZE = "compressedSize"; -const PROPERTY_NAME_OFFSET = "offset"; -const PROPERTY_NAME_DISK_NUMBER_START = "diskNumberStart"; -const PROPERTY_NAME_LAST_MODIFICATION_DATE = "lastModDate"; -const PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE = "rawLastModDate"; -const PROPERTY_NAME_LAST_ACCESS_DATE = "lastAccessDate"; -const PROPERTY_NAME_RAW_LAST_ACCESS_DATE = "rawLastAccessDate"; -const PROPERTY_NAME_CREATION_DATE = "creationDate"; -const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate"; -const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE = "internalFileAttribute"; -const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE = "externalFileAttribute"; -const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible"; -const PROPERTY_NAME_ZIP64 = "zip64"; - -const PROPERTY_NAMES = [ - PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, PROPERTY_NAME_COMPPRESSED_SIZE, PROPERTY_NAME_UNCOMPPRESSED_SIZE, - PROPERTY_NAME_LAST_MODIFICATION_DATE, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, - PROPERTY_NAME_LAST_ACCESS_DATE, PROPERTY_NAME_CREATION_DATE, PROPERTY_NAME_OFFSET, PROPERTY_NAME_DISK_NUMBER_START, - PROPERTY_NAME_DISK_NUMBER_START, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE, - PROPERTY_NAME_MS_DOS_COMPATIBLE, PROPERTY_NAME_ZIP64, - "directory", "bitFlag", "encrypted", "signature", "filenameUTF8", "commentUTF8", "compressionMethod", "version", "versionMadeBy", - "extraField", "rawExtraField", "extraFieldZip64", "extraFieldUnicodePath", "extraFieldUnicodeComment", "extraFieldAES", "extraFieldNTFS", - "extraFieldExtendedTimestamp"]; - -class Entry { - - constructor(data) { - PROPERTY_NAMES.forEach(name => this[name] = data[name]); - } - -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -const ERR_BAD_FORMAT = "File format is not recognized"; -const ERR_EOCDR_NOT_FOUND = "End of central directory not found"; -const ERR_EOCDR_ZIP64_NOT_FOUND = "End of Zip64 central directory not found"; -const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found"; -const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found"; -const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found"; -const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found"; -const ERR_ENCRYPTED = "File contains encrypted entry"; -const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported"; -const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported"; -const ERR_SPLIT_ZIP_FILE = "Split zip file"; -const CHARSET_UTF8 = "utf-8"; -const CHARSET_CP437 = "cp437"; -const ZIP64_PROPERTIES = [ - [PROPERTY_NAME_UNCOMPPRESSED_SIZE, MAX_32_BITS], - [PROPERTY_NAME_COMPPRESSED_SIZE, MAX_32_BITS], - [PROPERTY_NAME_OFFSET, MAX_32_BITS], - [PROPERTY_NAME_DISK_NUMBER_START, MAX_16_BITS] -]; -const ZIP64_EXTRACTION = { - [MAX_16_BITS]: { - getValue: getUint32, - bytes: 4 - }, - [MAX_32_BITS]: { - getValue: getBigUint64, - bytes: 8 - } -}; - -class ZipReader { - - constructor(reader, options = {}) { - Object.assign(this, { - reader: initReader(reader), - options, - config: getConfiguration() - }); - } - - async* getEntriesGenerator(options = {}) { - const zipReader = this; - let { reader } = zipReader; - const { config } = zipReader; - await initStream(reader); - if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) { - reader = new BlobReader(await new Response(reader.readable).blob()); - await initStream(reader); - } - if (reader.size < END_OF_CENTRAL_DIR_LENGTH) { - throw new Error(ERR_BAD_FORMAT); - } - reader.chunkSize = getChunkSize(config); - const endOfDirectoryInfo = await seekSignature(reader, END_OF_CENTRAL_DIR_SIGNATURE, reader.size, END_OF_CENTRAL_DIR_LENGTH, MAX_16_BITS * 16); - if (!endOfDirectoryInfo) { - const signatureArray = await readUint8Array(reader, 0, 4); - const signatureView = getDataView(signatureArray); - if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) { - throw new Error(ERR_SPLIT_ZIP_FILE); - } else { - throw new Error(ERR_EOCDR_NOT_FOUND); - } - } - const endOfDirectoryView = getDataView(endOfDirectoryInfo); - let directoryDataLength = getUint32(endOfDirectoryView, 12); - let directoryDataOffset = getUint32(endOfDirectoryView, 16); - const commentOffset = endOfDirectoryInfo.offset; - const commentLength = getUint16(endOfDirectoryView, 20); - const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength; - let lastDiskNumber = getUint16(endOfDirectoryView, 4); - const expectedLastDiskNumber = reader.lastDiskNumber || 0; - let diskNumber = getUint16(endOfDirectoryView, 6); - let filesLength = getUint16(endOfDirectoryView, 8); - let prependedDataLength = 0; - let startOffset = 0; - if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) { - const endOfDirectoryLocatorArray = await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH); - const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray); - if (getUint32(endOfDirectoryLocatorView, 0) != ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) { - throw new Error(ERR_EOCDR_ZIP64_NOT_FOUND); - } - directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8); - let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1); - let endOfDirectoryView = getDataView(endOfDirectoryArray); - const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH; - if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) { - const originalDirectoryDataOffset = directoryDataOffset; - directoryDataOffset = expectedDirectoryDataOffset; - prependedDataLength = directoryDataOffset - originalDirectoryDataOffset; - endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1); - endOfDirectoryView = getDataView(endOfDirectoryArray); - } - if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) { - throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND); - } - if (lastDiskNumber == MAX_16_BITS) { - lastDiskNumber = getUint32(endOfDirectoryView, 16); - } - if (diskNumber == MAX_16_BITS) { - diskNumber = getUint32(endOfDirectoryView, 20); - } - if (filesLength == MAX_16_BITS) { - filesLength = getBigUint64(endOfDirectoryView, 32); - } - if (directoryDataLength == MAX_32_BITS) { - directoryDataLength = getBigUint64(endOfDirectoryView, 40); - } - directoryDataOffset -= directoryDataLength; - } - if (expectedLastDiskNumber != lastDiskNumber) { - throw new Error(ERR_SPLIT_ZIP_FILE); - } - if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) { - throw new Error(ERR_BAD_FORMAT); - } - let offset = 0; - let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber); - let directoryView = getDataView(directoryArray); - if (directoryDataLength) { - const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - directoryDataLength; - if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) { - const originalDirectoryDataOffset = directoryDataOffset; - directoryDataOffset = expectedDirectoryDataOffset; - prependedDataLength = directoryDataOffset - originalDirectoryDataOffset; - directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber); - directoryView = getDataView(directoryArray); - } - } - if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) { - throw new Error(ERR_BAD_FORMAT); - } - const filenameEncoding = getOptionValue(zipReader, options, "filenameEncoding"); - const commentEncoding = getOptionValue(zipReader, options, "commentEncoding"); - for (let indexFile = 0; indexFile < filesLength; indexFile++) { - const fileEntry = new ZipEntry(reader, config, zipReader.options); - if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) { - throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND); - } - readCommonHeader(fileEntry, directoryView, offset + 6); - const languageEncodingFlag = Boolean(fileEntry.bitFlag.languageEncodingFlag); - const filenameOffset = offset + 46; - const extraFieldOffset = filenameOffset + fileEntry.filenameLength; - const commentOffset = extraFieldOffset + fileEntry.extraFieldLength; - const versionMadeBy = getUint16(directoryView, offset + 4); - const msDosCompatible = (versionMadeBy & 0) == 0; - const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset); - const commentLength = getUint16(directoryView, offset + 32); - const endOffset = commentOffset + commentLength; - const rawComment = directoryArray.subarray(commentOffset, endOffset); - const filenameUTF8 = languageEncodingFlag; - const commentUTF8 = languageEncodingFlag; - const directory = msDosCompatible && ((getUint8(directoryView, offset + 38) & FILE_ATTR_MSDOS_DIR_MASK) == FILE_ATTR_MSDOS_DIR_MASK); - const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength; - Object.assign(fileEntry, { - versionMadeBy, - msDosCompatible, - compressedSize: 0, - uncompressedSize: 0, - commentLength, - directory, - offset: offsetFileEntry, - diskNumberStart: getUint16(directoryView, offset + 34), - internalFileAttribute: getUint16(directoryView, offset + 36), - externalFileAttribute: getUint32(directoryView, offset + 38), - rawFilename, - filenameUTF8, - commentUTF8, - rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset) - }); - const [filename, comment] = await Promise.all([ - decodeText(rawFilename, filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437), - decodeText(rawComment, commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437) - ]); - Object.assign(fileEntry, { - rawComment, - filename, - comment, - directory: directory || filename.endsWith(DIRECTORY_SIGNATURE) - }); - startOffset = Math.max(offsetFileEntry, startOffset); - await readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6); - const entry = new Entry(fileEntry); - entry.getData = (writer, options) => fileEntry.getData(writer, entry, options); - offset = endOffset; - const { onprogress } = options; - if (onprogress) { - try { - await onprogress(indexFile + 1, filesLength, new Entry(fileEntry)); - } catch (_error) { - // ignored - } - } - yield entry; - } - const extractPrependedData = getOptionValue(zipReader, options, "extractPrependedData"); - const extractAppendedData = getOptionValue(zipReader, options, "extractAppendedData"); - if (extractPrependedData) { - zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : new Uint8Array(); - } - zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : new Uint8Array(); - if (extractAppendedData) { - zipReader.appendedData = appendedDataOffset < reader.size ? await readUint8Array(reader, appendedDataOffset, reader.size - appendedDataOffset) : new Uint8Array(); - } - return true; - } - - async getEntries(options = {}) { - const entries = []; - for await (const entry of this.getEntriesGenerator(options)) { - entries.push(entry); - } - return entries; - } - - async close() { - } -} - -class ZipEntry { - - constructor(reader, config, options) { - Object.assign(this, { - reader, - config, - options - }); - } - - async getData(writer, fileEntry, options = {}) { - const zipEntry = this; - const { - reader, - offset, - diskNumberStart, - extraFieldAES, - compressionMethod, - config, - bitFlag, - signature, - rawLastModDate, - uncompressedSize, - compressedSize - } = zipEntry; - const localDirectory = zipEntry.localDirectory = {}; - const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart); - const dataView = getDataView(dataArray); - let password = getOptionValue(zipEntry, options, "password"); - password = password && password.length && password; - if (extraFieldAES) { - if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) { - throw new Error(ERR_UNSUPPORTED_COMPRESSION); - } - } - if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE) { - throw new Error(ERR_UNSUPPORTED_COMPRESSION); - } - if (getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) { - throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND); - } - readCommonHeader(localDirectory, dataView, 4); - localDirectory.rawExtraField = localDirectory.extraFieldLength ? - await readUint8Array(reader, offset + 30 + localDirectory.filenameLength, localDirectory.extraFieldLength, diskNumberStart) : - new Uint8Array(); - await readCommonFooter(zipEntry, localDirectory, dataView, 4); - Object.assign(fileEntry, { - lastAccessDate: localDirectory.lastAccessDate, - creationDate: localDirectory.creationDate - }); - const encrypted = zipEntry.encrypted && localDirectory.encrypted; - const zipCrypto = encrypted && !extraFieldAES; - if (encrypted) { - if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) { - throw new Error(ERR_UNSUPPORTED_ENCRYPTION); - } else if (!password) { - throw new Error(ERR_ENCRYPTED); - } - } - const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength; - const readable = reader.readable; - readable.diskNumberStart = diskNumberStart; - readable.offset = dataOffset; - let size = readable.size = compressedSize; - const signal = getOptionValue(zipEntry, options, "signal"); - const checkPasswordOnly = getOptionValue(zipEntry, options, "checkPasswordOnly"); - if (checkPasswordOnly) { - writer = new WritableStream(); - } - writer = initWriter(writer); - await initStream(writer, uncompressedSize); - const { writable } = writer; - const { onstart, onprogress, onend } = options; - const workerOptions = { - options: { - codecType: CODEC_INFLATE, - password, - zipCrypto, - encryptionStrength: extraFieldAES && extraFieldAES.strength, - signed: getOptionValue(zipEntry, options, "checkSignature"), - passwordVerification: zipCrypto && (bitFlag.dataDescriptor ? ((rawLastModDate >>> 8) & 0xFF) : ((signature >>> 24) & 0xFF)), - signature, - compressed: compressionMethod != 0, - encrypted, - useWebWorkers: getOptionValue(zipEntry, options, "useWebWorkers"), - useCompressionStream: getOptionValue(zipEntry, options, "useCompressionStream"), - transferStreams: getOptionValue(zipEntry, options, "transferStreams"), - checkPasswordOnly - }, - config, - streamOptions: { signal, size, onstart, onprogress, onend } - }; - let outputSize = 0; - try { - ({ outputSize } = (await runWorker({ readable, writable }, workerOptions))); - } catch (error) { - if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) { - throw error; - } - } finally { - const preventClose = getOptionValue(zipEntry, options, "preventClose"); - writable.size += outputSize; - if (!preventClose && !writable.locked) { - await writable.close(); - } - } - return checkPasswordOnly ? undefined : writer.getData ? writer.getData() : writable; - } -} - -function readCommonHeader(directory, dataView, offset) { - const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2); - const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED; - const rawLastModDate = getUint32(dataView, offset + 6); - Object.assign(directory, { - encrypted, - version: getUint16(dataView, offset), - bitFlag: { - level: (rawBitFlag & BITFLAG_LEVEL) >> 1, - dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR, - languageEncodingFlag: (rawBitFlag & BITFLAG_LANG_ENCODING_FLAG) == BITFLAG_LANG_ENCODING_FLAG - }, - rawLastModDate, - lastModDate: getDate(rawLastModDate), - filenameLength: getUint16(dataView, offset + 22), - extraFieldLength: getUint16(dataView, offset + 24) - }); -} - -async function readCommonFooter(fileEntry, directory, dataView, offset) { - const { rawExtraField } = directory; - const extraField = directory.extraField = new Map(); - const rawExtraFieldView = getDataView(new Uint8Array(rawExtraField)); - let offsetExtraField = 0; - try { - while (offsetExtraField < rawExtraField.length) { - const type = getUint16(rawExtraFieldView, offsetExtraField); - const size = getUint16(rawExtraFieldView, offsetExtraField + 2); - extraField.set(type, { - type, - data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size) - }); - offsetExtraField += 4 + size; - } - } catch (_error) { - // ignored - } - const compressionMethod = getUint16(dataView, offset + 4); - Object.assign(directory, { - signature: getUint32(dataView, offset + 10), - uncompressedSize: getUint32(dataView, offset + 18), - compressedSize: getUint32(dataView, offset + 14) - }); - const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64); - if (extraFieldZip64) { - readExtraFieldZip64(extraFieldZip64, directory); - directory.extraFieldZip64 = extraFieldZip64; - } - const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH); - if (extraFieldUnicodePath) { - await readExtraFieldUnicode(extraFieldUnicodePath, PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, directory, fileEntry); - directory.extraFieldUnicodePath = extraFieldUnicodePath; - } - const extraFieldUnicodeComment = extraField.get(EXTRAFIELD_TYPE_UNICODE_COMMENT); - if (extraFieldUnicodeComment) { - await readExtraFieldUnicode(extraFieldUnicodeComment, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, directory, fileEntry); - directory.extraFieldUnicodeComment = extraFieldUnicodeComment; - } - const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES); - if (extraFieldAES) { - readExtraFieldAES(extraFieldAES, directory, compressionMethod); - directory.extraFieldAES = extraFieldAES; - } else { - directory.compressionMethod = compressionMethod; - } - const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS); - if (extraFieldNTFS) { - readExtraFieldNTFS(extraFieldNTFS, directory); - directory.extraFieldNTFS = extraFieldNTFS; - } - const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP); - if (extraFieldExtendedTimestamp) { - readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory); - directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp; - } -} - -function readExtraFieldZip64(extraFieldZip64, directory) { - directory.zip64 = true; - const extraFieldView = getDataView(extraFieldZip64.data); - const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max); - for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) { - const [propertyName, max] = missingProperties[indexMissingProperty]; - if (directory[propertyName] == max) { - const extraction = ZIP64_EXTRACTION[max]; - directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset); - offset += extraction.bytes; - } else if (extraFieldZip64[propertyName]) { - throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND); - } - } -} - -async function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) { - const extraFieldView = getDataView(extraFieldUnicode.data); - const crc32 = new Crc32(); - crc32.append(fileEntry[rawPropertyName]); - const dataViewSignature = getDataView(new Uint8Array(4)); - dataViewSignature.setUint32(0, crc32.get(), true); - Object.assign(extraFieldUnicode, { - version: getUint8(extraFieldView, 0), - signature: getUint32(extraFieldView, 1), - [propertyName]: await decodeText(extraFieldUnicode.data.subarray(5)), - valid: !fileEntry.bitFlag.languageEncodingFlag && extraFieldUnicode.signature == getUint32(dataViewSignature, 0) - }); - if (extraFieldUnicode.valid) { - directory[propertyName] = extraFieldUnicode[propertyName]; - directory[propertyName + "UTF8"] = true; - } -} - -function readExtraFieldAES(extraFieldAES, directory, compressionMethod) { - const extraFieldView = getDataView(extraFieldAES.data); - const strength = getUint8(extraFieldView, 4); - Object.assign(extraFieldAES, { - vendorVersion: getUint8(extraFieldView, 0), - vendorId: getUint8(extraFieldView, 2), - strength, - originalCompressionMethod: compressionMethod, - compressionMethod: getUint16(extraFieldView, 5) - }); - directory.compressionMethod = extraFieldAES.compressionMethod; -} - -function readExtraFieldNTFS(extraFieldNTFS, directory) { - const extraFieldView = getDataView(extraFieldNTFS.data); - let offsetExtraField = 4; - let tag1Data; - try { - while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) { - const tagValue = getUint16(extraFieldView, offsetExtraField); - const attributeSize = getUint16(extraFieldView, offsetExtraField + 2); - if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) { - tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize); - } - offsetExtraField += 4 + attributeSize; - } - } catch (_error) { - // ignored - } - try { - if (tag1Data && tag1Data.length == 24) { - const tag1View = getDataView(tag1Data); - const rawLastModDate = tag1View.getBigUint64(0, true); - const rawLastAccessDate = tag1View.getBigUint64(8, true); - const rawCreationDate = tag1View.getBigUint64(16, true); - Object.assign(extraFieldNTFS, { - rawLastModDate, - rawLastAccessDate, - rawCreationDate - }); - const lastModDate = getDateNTFS(rawLastModDate); - const lastAccessDate = getDateNTFS(rawLastAccessDate); - const creationDate = getDateNTFS(rawCreationDate); - const extraFieldData = { lastModDate, lastAccessDate, creationDate }; - Object.assign(extraFieldNTFS, extraFieldData); - Object.assign(directory, extraFieldData); - } - } catch (_error) { - // ignored - } -} - -function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory) { - const extraFieldView = getDataView(extraFieldExtendedTimestamp.data); - const flags = getUint8(extraFieldView, 0); - const timeProperties = []; - const timeRawProperties = []; - if ((flags & 0x1) == 0x1) { - timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE); - timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE); - } - if ((flags & 0x2) == 0x2) { - timeProperties.push(PROPERTY_NAME_LAST_ACCESS_DATE); - timeRawProperties.push(PROPERTY_NAME_RAW_LAST_ACCESS_DATE); - } - if ((flags & 0x4) == 0x4) { - timeProperties.push(PROPERTY_NAME_CREATION_DATE); - timeRawProperties.push(PROPERTY_NAME_RAW_CREATION_DATE); - } - let offset = 1; - timeProperties.forEach((propertyName, indexProperty) => { - if (extraFieldExtendedTimestamp.data.length >= offset + 4) { - const time = getUint32(extraFieldView, offset); - directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date(time * 1000); - const rawPropertyName = timeRawProperties[indexProperty]; - extraFieldExtendedTimestamp[rawPropertyName] = time; - } - offset += 4; - }); -} - -async function seekSignature(reader, signature, startOffset, minimumBytes, maximumLength) { - const signatureArray = new Uint8Array(4); - const signatureView = getDataView(signatureArray); - setUint32(signatureView, 0, signature); - const maximumBytes = minimumBytes + maximumLength; - return (await seek(minimumBytes)) || await seek(Math.min(maximumBytes, startOffset)); - - async function seek(length) { - const offset = startOffset - length; - const bytes = await readUint8Array(reader, offset, length); - for (let indexByte = bytes.length - minimumBytes; indexByte >= 0; indexByte--) { - if (bytes[indexByte] == signatureArray[0] && bytes[indexByte + 1] == signatureArray[1] && - bytes[indexByte + 2] == signatureArray[2] && bytes[indexByte + 3] == signatureArray[3]) { - return { - offset: offset + indexByte, - buffer: bytes.slice(indexByte, indexByte + minimumBytes).buffer - }; - } - } - } -} - -function getOptionValue(zipReader, options, name) { - return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name]; -} - -function getDate(timeRaw) { - const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; - try { - return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0); - } catch (_error) { - // ignored - } -} - -function getDateNTFS(timeRaw) { - return new Date((Number((timeRaw / BigInt(10000)) - BigInt(11644473600000)))); -} - -function getUint8(view, offset) { - return view.getUint8(offset); -} - -function getUint16(view, offset) { - return view.getUint16(offset, true); -} - -function getUint32(view, offset) { - return view.getUint32(offset, true); -} - -function getBigUint64(view, offset) { - return Number(view.getBigUint64(offset, true)); -} - -function setUint32(view, offset, value) { - view.setUint32(offset, value, true); -} - -function getDataView(array) { - return new DataView(array.buffer); -} - -/* - Copyright (c) 2022 Gildas Lormeau. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -let baseURL; -try { - baseURL = import.meta.url; -} catch (_error) { - // ignored -} -configure({ baseURL }); -e(configure); - -/// - -configure({ Deflate: ZipDeflate, Inflate: ZipInflate }); - -function parseIndex(index, size) { - return index < 0 ? - Math.max(index + size, 0) : - Math.min(index, size); -} -class BlobEntryReaderImpl extends Reader { - constructor(blob, entryMetadata) { - super(blob); - this.blob = blob; - this.offset = entryMetadata.offset + entryMetadata.headerSize; - this.size = entryMetadata.compressedSize; - } - async readUint8Array(index, length) { - const start = parseIndex(index, this.size) + this.offset; - const end = parseIndex(index + length, this.size) + this.offset; - const blob = this.blob.slice(start, end); - return new Uint8Array(await blob.arrayBuffer()); - } -} -/** - * Represents a {@link Reader} instance used to read data of an entry in a zip - * file provided as a {@link Blob}. It directly reads data if it is uncompressed. - */ -class BlobEntryReader extends Reader { - /** - * @param blob - The blob to read data from, usually the outer zip file. - * @param entry - The entry to read data of, usually the inner zip file. - * @param mimeString - The MIME type of the data. - * @param options - Represents options passed to {@link Entry#getData}. - */ - constructor(blob, entry, mimeString, options) { - super(); - this.blob = blob; - this.entry = entry; - this.mimeString = mimeString; - this.options = options; - } - async init() { - const entryMetadata = await getEntryMetadata(this.blob, this.entry); - if (entryMetadata.compressionMethod !== 0) { - const entryBlob = await zipGetData(this.entry, new BlobWriter(this.mimeString), this.options); - this.reader = new BlobReader(entryBlob); - } - else { - this.reader = new BlobEntryReaderImpl(this.blob, entryMetadata); - } - this.size = this.reader.size; - } - async readUint8Array(index, length) { - return this.reader.readUint8Array(index, length); - } -} - -// Images needed for fastbootd -const BOOT_CRITICAL_IMAGES = [ - "boot", - "dt", - "dtbo", - "init_boot", - "pvmfw", - "recovery", - "vbmeta_system", - "vbmeta_vendor", - "vbmeta", - "vendor_boot", - "vendor_kernel_boot", -]; -// Less critical images to flash after boot-critical ones -const SYSTEM_IMAGES = [ - "odm", - "odm_dlkm", - "product", - "system_dlkm", - "system_ext", - "system", - "vendor_dlkm", - "vendor", -]; -/** - * User-friendly action strings for factory image flashing progress. - * This can be indexed by the action argument in FactoryFlashCallback. - */ -const USER_ACTION_MAP = { - load: "Loading", - unpack: "Unpacking", - flash: "Writing", - wipe: "Wiping", - reboot: "Restarting", -}; -const BOOTLOADER_REBOOT_TIME = 4000; // ms -const FASTBOOTD_REBOOT_TIME = 16000; // ms -const USERDATA_ERASE_TIME = 1000; // ms -async function flashEntryBlob(device, entry, onProgress, partition) { - const blob = await zipGetData(entry, new BlobWriter("application/octet-stream"), { - onstart(total) { - logDebug(`Unpacking ${partition} (${total} bytes)`); - onProgress("unpack", partition, 0.0); - - }, - onprogress(progress, total) { - onProgress("unpack", partition, progress / total); - - } - }); - logDebug(`Flashing ${partition}`); - onProgress("flash", partition, 0.0); - await device.flashBlob(partition, blob, (progress) => { - onProgress("flash", partition, progress); - }); -} -async function tryFlashImages(device, entries, onProgress, imageNames) { - for (let imageName of imageNames) { - let pattern = new RegExp(`${imageName}(?:-.+)?\\.img$`); - let entry = entries.find((entry) => entry.filename.match(pattern)); - if (entry !== undefined) { - if (imageName == "bootloader") { - let current_slot = await device.getVariable("current-slot"); - if (current_slot == "a") { - await flashEntryBlob(device, entry, onProgress, (imageName + "_b")); - await device.runCommand("set_active:b"); - } - else if (current_slot == "b") { - await flashEntryBlob(device, entry, onProgress, (imageName + "_a")); - await device.runCommand("set_active:a"); - } - else { - throw new FastbootError("FAIL", `Invalid slot given by bootloader.`); - } - } - else { - await flashEntryBlob(device, entry, onProgress, imageName); - } - } - } -} -async function checkRequirements(device, androidInfo) { - // Deal with CRLF just in case - for (let line of androidInfo.replace("\r", "").split("\n")) { - let match = line.match(/^require\s+(.+?)=(.+)$/); - if (!match) { - continue; - } - let variable = match[1]; - // Historical mismatch that we still need to deal with - if (variable === "board") { - variable = "product"; - } - let expectValue = match[2]; - let expectValues = expectValue.split("|"); - // Special case: not a real variable at all - if (variable === "partition-exists") { - // Check whether the partition exists on the device: - // has-slot = undefined || FAIL => doesn't exist - // has-slot = yes || no => exists - let hasSlot = await device.getVariable(`has-slot:${expectValue}`); - if (hasSlot !== "yes" && hasSlot !== "no") { - throw new FastbootError("FAIL", `Requirement ${variable}=${expectValue} failed, device lacks partition`); - } - // Check whether we recognize the partition - if (!BOOT_CRITICAL_IMAGES.includes(expectValue) && - !SYSTEM_IMAGES.includes(expectValue)) { - throw new FastbootError("FAIL", `Requirement ${variable}=${expectValue} failed, unrecognized partition`); - } - } - else { - let realValue = await device.getVariable(variable); - if (expectValues.includes(realValue)) { - logDebug(`Requirement ${variable}=${expectValue} passed`); - } - else { - let msg = `Requirement ${variable}=${expectValue} failed, value = ${realValue}`; - logDebug(msg); - throw new FastbootError("FAIL", msg); - } - } - } -} -async function tryReboot(device, target, onReconnect) { - try { - await device.reboot(target, false); - } - catch (e) { - /* Failed = device rebooted by itself */ - } - await device.waitForConnect(onReconnect); -} -async function flashRecovery(device, partition, blob, onReconnect, onProgress = (_progress) => { }) { - await device.flashBlob(partition, blob, (progress) => { - onProgress(progress); - }); -} -async function flashZip(device, blob, wipe, onReconnect, onProgress = (_action, _item, _progress) => { }) { - onProgress("load", "package", 0.0); - let reader = new ZipReader(new BlobReader(blob)); - let entries = await reader.getEntries(); - // Bootloader and radio packs can only be flashed in the bare-metal bootloader - if ((await device.getVariable("is-userspace")) === "yes") { - await device.reboot("bootloader", true, onReconnect); - } - // 1. Bootloader pack (repeated for slot A and B) - await tryFlashImages(device, entries, onProgress, ["bootloader"]); - await runWithTimedProgress(onProgress, "reboot", "device", BOOTLOADER_REBOOT_TIME, tryReboot(device, "bootloader", onReconnect)); - await tryFlashImages(device, entries, onProgress, ["bootloader"]); - await runWithTimedProgress(onProgress, "reboot", "device", BOOTLOADER_REBOOT_TIME, tryReboot(device, "bootloader", onReconnect)); - // 2. Radio pack - await tryFlashImages(device, entries, onProgress, ["radio"]); - await runWithTimedProgress(onProgress, "reboot", "device", BOOTLOADER_REBOOT_TIME, tryReboot(device, "bootloader", onReconnect)); - // Cancel snapshot update if in progress - let snapshotStatus = await device.getVariable("snapshot-update-status"); - if (snapshotStatus !== null && snapshotStatus !== "none") { - await device.runCommand("snapshot-update:cancel"); - } - // Load nested images for the following steps - let entry = entries.find((e) => e.filename.match(/image-.+\.zip$/)); - const imageReader = new ZipReader(new BlobEntryReader(blob, entry, "application/zip", { - onstart(total) { - logDebug(`Loading nested images from zip (${total} bytes)`); - onProgress("unpack", "images", 0.0); - - }, - onprogress(progress, total) { - onProgress("unpack", "images", progress / total); - - } - })); - const imageEntries = await imageReader.getEntries(); - // 3. Check requirements - entry = imageEntries.find((e) => e.filename === "android-info.txt"); - if (entry !== undefined) { - const reqText = await zipGetData(entry, new TextWriter()); - await checkRequirements(device, reqText); - } - // 4. Boot-critical images - await tryFlashImages(device, imageEntries, onProgress, BOOT_CRITICAL_IMAGES); - // 5. Super partition template - // This is also where we reboot to fastbootd. - entry = imageEntries.find((e) => e.filename === "super_empty.img"); - if (entry !== undefined) { - await runWithTimedProgress(onProgress, "reboot", "device", FASTBOOTD_REBOOT_TIME, device.reboot("fastboot", true, onReconnect)); - let superName = await device.getVariable("super-partition-name"); - if (!superName) { - superName = "super"; - } - let superAction = wipe ? "wipe" : "flash"; - onProgress(superAction, "super", 0.0); - const superBlob = await zipGetData(entry, new BlobWriter("application/octet-stream")); - await device.upload(superName, await readBlobAsBuffer(superBlob), (progress) => { - onProgress(superAction, "super", progress); - }); - await device.runCommand(`update-super:${superName}${wipe ? ":wipe" : ""}`); - } - // 6. Remaining system images - await tryFlashImages(device, imageEntries, onProgress, SYSTEM_IMAGES); - // We unconditionally reboot back to the bootloader here if we're in fastbootd, - // even when there's no custom AVB key, because common follow-up actions like - // locking the bootloader and wiping data need to be done in the bootloader. - if ((await device.getVariable("is-userspace")) === "yes") { - await runWithTimedProgress(onProgress, "reboot", "device", BOOTLOADER_REBOOT_TIME, device.reboot("bootloader", true, onReconnect)); - } - // 7. Custom AVB key - entry = entries.find((e) => e.filename.endsWith("avb_pkmd.bin")); - if (entry !== undefined) { - await device.runCommand("erase:avb_custom_key"); - await flashEntryBlob(device, entry, onProgress, "avb_custom_key"); - } - // 8. Wipe userdata - if (wipe) { - await runWithTimedProgress(onProgress, "wipe", "data", USERDATA_ERASE_TIME, device.runCommand("erase:userdata")); - } -} - -const FASTBOOT_USB_CLASS = 0xff; -const FASTBOOT_USB_SUBCLASS = 0x42; -const FASTBOOT_USB_PROTOCOL = 0x03; -const BULK_TRANSFER_SIZE = 16384; -const DEFAULT_DOWNLOAD_SIZE = 512 * 1024 * 1024; // 512 MiB -// To conserve RAM and work around Chromium's ~2 GiB size limit, we limit the -// max download size even if the bootloader can accept more data. -const MAX_DOWNLOAD_SIZE = 1024 * 1024 * 1024; // 1 GiB -const GETVAR_TIMEOUT = 10000; // ms -/** - * Exception class for USB errors not directly thrown by WebUSB. - */ -class UsbError extends Error { - constructor(message) { - super(message); - this.name = "UsbError"; - } -} -/** - * Exception class for errors returned by the bootloader, as well as high-level - * fastboot errors resulting from bootloader responses. - */ -class FastbootError extends Error { - constructor(status, message) { - super(`Bootloader replied with ${status}: ${message}`); - this.status = status; - this.bootloaderMessage = message; - this.name = "FastbootError"; - } -} -/** - * This class is a client for executing fastboot commands and operations on a - * device connected over USB. - */ -class FastbootDevice { - /** - * Create a new fastboot device instance. This doesn't actually connect to - * any USB devices; call {@link connect} to do so. - */ - constructor() { - this.device = null; - this.epIn = null; - this.epOut = null; - this._registeredUsbListeners = false; - this._connectResolve = null; - this._connectReject = null; - this._disconnectResolve = null; - } - /** - * Returns whether a USB device is connected and ready for use. - */ - get isConnected() { - return (this.device !== null && - this.device.opened && - this.device.configurations[0].interfaces[0].claimed); - } - /** - * Validate the current USB device's details and connect to it. - * - * @private - */ - async _validateAndConnectDevice() { - if (this.device === null) { - throw new UsbError("Attempted to connect to null device"); - } - // Validate device - let ife = this.device.configurations[0].interfaces[0].alternates[0]; - if (ife.endpoints.length !== 2) { - throw new UsbError("Interface has wrong number of endpoints"); - } - this.epIn = null; - this.epOut = null; - for (let endpoint of ife.endpoints) { - logVerbose("Checking endpoint:", endpoint); - if (endpoint.type !== "bulk") { - throw new UsbError("Interface endpoint is not bulk"); - } - if (endpoint.direction === "in") { - if (this.epIn === null) { - this.epIn = endpoint.endpointNumber; - } - else { - throw new UsbError("Interface has multiple IN endpoints"); - } - } - else if (endpoint.direction === "out") { - if (this.epOut === null) { - this.epOut = endpoint.endpointNumber; - } - else { - throw new UsbError("Interface has multiple OUT endpoints"); - } - } - } - logVerbose("Endpoints: in =", this.epIn, ", out =", this.epOut); - try { - await this.device.open(); - // Opportunistically reset to fix issues on some platforms - try { - await this.device.reset(); - } - catch (error) { - /* Failed = doesn't support reset */ - } - await this.device.selectConfiguration(1); - await this.device.claimInterface(0); // fastboot - } - catch (error) { - // Propagate exception from waitForConnect() - if (this._connectReject !== null) { - this._connectReject(error); - this._connectResolve = null; - this._connectReject = null; - } - throw error; - } - // Return from waitForConnect() - if (this._connectResolve !== null) { - this._connectResolve(undefined); - this._connectResolve = null; - this._connectReject = null; - } - } - /** - * Wait for the current USB device to disconnect, if it's still connected. - * Returns immediately if no device is connected. - */ - async waitForDisconnect() { - if (this.device === null) { - return; - } - return await new Promise((resolve, _reject) => { - this._disconnectResolve = resolve; - }); - } - /** - * Wait for the USB device to connect. Returns at the next connection, - * regardless of whether the connected USB device matches the previous one. - * - * @param {ReconnectCallback} onReconnect - Callback to request device reconnection on Android. - */ - async waitForConnect(onReconnect = () => { }) { - // On Android, we need to request the user to reconnect the device manually - // because there is no support for automatic reconnection. - if (navigator.userAgent.includes("Android")) { - await this.waitForDisconnect(); - onReconnect(); - } - return await new Promise((resolve, reject) => { - this._connectResolve = resolve; - this._connectReject = reject; - }); - } - - handleUSBDisconnect = async (event) => { - if (event.device === this.device) { - logDebug("USB device disconnected"); - if (this._disconnectResolve !== null) { - this._disconnectResolve(undefined); - this._disconnectResolve = null; - } - await window.navigator.usb.removeEventListener("connect", this.handleUSBConnect); - await window.navigator.usb.removeEventListener("disconnect", this.handleUSBDisconnect); - } - }; - - handleUSBConnect = async (event) => { - logDebug("USB device connected"); - this.device = event.device; - - let hasPromiseReject = this._connectReject !== null; - - try { - await this._validateAndConnectDevice(); - } catch (error) { - if (!hasPromiseReject) { - throw error; - } - } - }; - - /** - * Request the user to select a USB device and connect to it using the - * fastboot protocol. - * - * @throws {UsbError} - */ - async connect() { - let devices = await navigator.usb.getDevices(); - logDebug("Found paired USB devices:", devices); - if (devices.length === 1) { - this.device = devices[0]; - } - else { - // If multiple paired devices are connected, request the user to - // select a specific one to reduce ambiguity. This is also necessary - // if no devices are already paired, i.e. first use. - logDebug("No or multiple paired devices are connected, requesting one"); - this.device = await navigator.usb.requestDevice({ - filters: [ - { - classCode: FASTBOOT_USB_CLASS, - subclassCode: FASTBOOT_USB_SUBCLASS, - protocolCode: FASTBOOT_USB_PROTOCOL, - }, - ], - }); - } - logDebug("Using USB device:", this.device); - if (!this._registeredUsbListeners) { - navigator.usb.addEventListener("disconnect", this.handleUSBDisconnect); - navigator.usb.addEventListener("connect", this.handleUSBConnect); - this._registeredUsbListeners = true; - } - await this._validateAndConnectDevice(); - } - /** - * Read a raw command response from the bootloader. - * - * @private - * @returns {Promise} Object containing response text and data size, if any. - * @throws {FastbootError} - */ - async _readResponse() { - let respData = { - text: "", - }; - let respStatus; - do { - let respPacket = await this.device.transferIn(this.epIn, 64); - let response = new TextDecoder().decode(respPacket.data); - respStatus = response.substring(0, 4); - let respMessage = response.substring(4); - logDebug(`Response: ${respStatus} ${respMessage}`); - if (respStatus === "OKAY") { - // OKAY = end of response for this command - respData.text += respMessage; - } - else if (respStatus === "INFO") { - // INFO = additional info line - respData.text += respMessage + "\n"; - } - else if (respStatus === "DATA") { - // DATA = hex string, but it's returned separately for safety - respData.dataSize = respMessage; - } - else { - // Assume FAIL or garbage data - throw new FastbootError(respStatus, respMessage); - } - // INFO = more packets are coming - } while (respStatus === "INFO"); - return respData; - } - /** - * Send a textual command to the bootloader and read the response. - * This is in raw fastboot format, not AOSP fastboot syntax. - * - * @param {string} command - The command to send. - * @returns {Promise} Object containing response text and data size, if any. - * @throws {FastbootError} - */ - async runCommand(command) { - // Command and response length is always 64 bytes regardless of protocol - if (command.length > 64) { - throw new RangeError(); - } - // Send raw UTF-8 command - let cmdPacket = new TextEncoder().encode(command); - await this.device.transferOut(this.epOut, cmdPacket); - logDebug("Command:", command); - return this._readResponse(); - } - /** - * Read the value of a bootloader variable. Returns undefined if the variable - * does not exist. - * - * @param {string} varName - The name of the variable to get. - * @returns {Promise} Textual content of the variable. - * @throws {FastbootError} - */ - async getVariable(varName) { - let resp; - try { - resp = (await runWithTimeout(this.runCommand(`getvar:${varName}`), GETVAR_TIMEOUT)).text; - } - catch (error) { - // Some bootloaders return FAIL instead of empty responses, despite - // what the spec says. Normalize it here. - console.log(error) - if (error instanceof FastbootError && error.status == "FAIL") { - resp = null; - } - else { - throw error; - } - } - // Some bootloaders send whitespace around some variables. - // According to the spec, non-existent variables should return empty - // responses - return resp ? resp.trim() : null; - } - /** - * Get the maximum download size for a single payload, in bytes. - * - * @private - * @returns {Promise} - * @throws {FastbootError} - */ - async _getDownloadSize() { - try { - let resp = (await this.getVariable("max-download-size")).toLowerCase(); - if (resp) { - // AOSP fastboot requires hex - return Math.min(parseInt(resp, 16), MAX_DOWNLOAD_SIZE); - } - } - catch (error) { - /* Failed = no value, fallthrough */ - } - // FAIL or empty variable means no max, set a reasonable limit to conserve memory - return DEFAULT_DOWNLOAD_SIZE; - } - /** - * Send a raw data payload to the bootloader. - * - * @private - */ - async _sendRawPayload(buffer, onProgress) { - let i = 0; - let remainingBytes = buffer.byteLength; - while (remainingBytes > 0) { - let chunk = buffer.slice(i * BULK_TRANSFER_SIZE, (i + 1) * BULK_TRANSFER_SIZE); - if (i % 1000 === 0) { - logVerbose(` Sending ${chunk.byteLength} bytes to endpoint, ${remainingBytes} remaining, i=${i}`); - } - if (i % 10 === 0) { - onProgress((buffer.byteLength - remainingBytes) / buffer.byteLength); - } - await this.device.transferOut(this.epOut, chunk); - remainingBytes -= chunk.byteLength; - i += 1; - } - onProgress(1.0); - } - /** - * Upload a payload to the bootloader for later use, e.g. flashing. - * Does not handle raw images, flashing, or splitting. - * - * @param {string} partition - Name of the partition the payload is intended for. - * @param {ArrayBuffer} buffer - Buffer containing the data to upload. - * @param {FlashProgressCallback} onProgress - Callback for upload progress updates. - * @throws {FastbootError} - */ - async upload(partition, buffer, onProgress = (_progress) => { }) { - // Bootloader requires an 8-digit hex number - let xferHex = buffer.byteLength.toString(16).padStart(8, "0"); - if (xferHex.length !== 8) { - throw new FastbootError("FAIL", `Transfer size overflow: ${xferHex} is more than 8 digits`); - } - // Check with the device and make sure size matches - let downloadResp = await this.runCommand(`download:${xferHex}`); - if (downloadResp.dataSize === undefined) { - throw new FastbootError("FAIL", `Unexpected response to download command: ${downloadResp.text}`); - } - let downloadSize = parseInt(downloadResp.dataSize, 16); - if (downloadSize !== buffer.byteLength) { - throw new FastbootError("FAIL", `Bootloader wants ${buffer.byteLength} bytes, requested to send ${buffer.byteLength} bytes`); - } - await this._sendRawPayload(buffer, onProgress); - await this._readResponse(); - } - /** - * Reboot to the given target, and optionally wait for the device to - * reconnect. - * - * @param {string} target - Where to reboot to, i.e. fastboot or bootloader. - * @param {boolean} wait - Whether to wait for the device to reconnect. - * @param {ReconnectCallback} onReconnect - Callback to request device reconnection, if wait is enabled. - */ - async reboot(target = "", wait = false, onReconnect = () => { }) { - if (target.length > 0) { - await this.runCommand(`reboot-${target}`); - } - else { - await this.runCommand("reboot"); - } - if (wait) { - await this.waitForConnect(onReconnect); - } - } - /** - * Flash the given Blob to the given partition on the device. Any image - * format supported by the bootloader is allowed, e.g. sparse or raw images. - * Large raw images will be converted to sparse images automatically, and - * large sparse images will be split and flashed in multiple passes - * depending on the bootloader's payload size limit. - * - * @param {string} partition - The name of the partition to flash. - * @param {Blob} blob - The Blob to retrieve data from. - * @param {FlashProgressCallback} onProgress - Callback for flashing progress updates. - * @throws {FastbootError} - */ - async flashBlob(partition, blob, onProgress = (_progress) => { }) { - // Use current slot if partition is A/B - if ((await this.getVariable(`has-slot:${partition}`)) === "yes") { - partition += "_" + (await this.getVariable("current-slot")); - } - let maxDlSize = (await this._getDownloadSize() /4) * 3; - - let fileHeader = await readBlobAsBuffer(blob.slice(0, FILE_HEADER_SIZE)); - let totalBytes = blob.size; - let isSparse = false; - try { - let sparseHeader = parseFileHeader(fileHeader); - if (sparseHeader !== null) { - totalBytes = sparseHeader.blocks * sparseHeader.blockSize; - isSparse = true; - } - } - catch (error) { - console.log(error) - // ImageError = invalid, so keep blob.size - } - // Logical partitions need to be resized before flashing because they're - // sized perfectly to the payload. - if ((await this.getVariable(`is-logical:${partition}`)) === "yes") { - // As per AOSP fastboot, we reset the partition to 0 bytes first - // to optimize extent allocation. - await this.runCommand(`resize-logical-partition:${partition}:0`); - // Set the actual size - await this.runCommand(`resize-logical-partition:${partition}:${totalBytes}`); - } - // Convert image to sparse (for splitting) if it exceeds the size limit - if (blob.size > maxDlSize && !isSparse) { - logDebug(`${partition} image is raw, converting to sparse`); - blob = await fromRaw(blob); - } - logDebug(`Flashing ${blob.size} bytes to ${partition}, ${maxDlSize} bytes per split`); - let splits = 0; - let sentBytes = 0; - for await (let split of splitBlob(blob, maxDlSize)) { - await this.upload(partition, split.data, (progress) => { - onProgress((sentBytes + progress * split.bytes) / totalBytes); - }); - logDebug("Flashing payload..."); - await this.runCommand(`flash:${partition}`); - splits += 1; - sentBytes += split.bytes; - } - logDebug(`Flashed ${partition} with ${splits} split(s)`); - } - /** - * Flash Removery using the given Blob on the device. - * Equivalent to `fastboot flash vendor[_boot] recovery.img`. - * - * @param {Blob} blob - The Blob to retrieve data from. - * @param {string} name - The recovery name with extension. - * @param {FlashProgressCallback} onProgress - Callback for flashing progress updates. - * @throws {FastbootError} - */ - async flashRecoveryBlob(blob, name, onReconnect, onProgress = (_progress) => { }) { - logDebug(`Flashing ${name} ${blob.size} bytes image`); - await readBlobAsBuffer(blob); - await flashRecovery(this, name, blob, onReconnect, onProgress); //device, entry, onProgress, imageName); - logDebug(`Flashed ${name} ${blob.size} bytes image`); - } - /** - * Boot the given Blob on the device. - * Equivalent to `fastboot boot boot.img`. - * - * @param {Blob} blob - The Blob to retrieve data from. - * @param {FlashProgressCallback} onProgress - Callback for flashing progress updates. - * @throws {FastbootError} - */ - async bootBlob(blob, onProgress = (_progress) => { }) { - logDebug(`Booting ${blob.size} bytes image`); - let data = await readBlobAsBuffer(blob); - await this.upload("boot.img", data, onProgress); - logDebug("Booting payload..."); - await this.runCommand("boot"); - logDebug(`Booted ${blob.size} bytes image`); - } - /** - * Flash the given factory images zip onto the device, with automatic handling - * of firmware, system, and logical partitions as AOSP fastboot and - * flash-all.sh would do. - * Equivalent to `fastboot update name.zip`. - * - * @param {Blob} blob - Blob containing the zip file to flash. - * @param {boolean} wipe - Whether to wipe super and userdata. Equivalent to `fastboot -w`. - * @param {ReconnectCallback} onReconnect - Callback to request device reconnection. - * @param {FactoryProgressCallback} onProgress - Progress callback for image flashing. - */ - async flashFactoryZip(blob, wipe, onReconnect, onProgress = (_progress) => { }) { - return await flashZip(this, blob, wipe, onReconnect, onProgress); - } -} - -export { FastbootDevice, FastbootError, TimeoutError, USER_ACTION_MAP, UsbError, configure as configureZip, setDebugLevel }; diff --git a/app/src/lib/fastboot/vendor/pako_inflate.min.js b/app/src/lib/fastboot/vendor/pako_inflate.min.js deleted file mode 100644 index 587fbdd52115bb7d7215e0aeab5398280a4b1fdd..0000000000000000000000000000000000000000 --- a/app/src/lib/fastboot/vendor/pako_inflate.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).pako={})}(this,(function(e){"use strict";var t=(e,t,i,n)=>{let a=65535&e|0,r=e>>>16&65535|0,o=0;for(;0!==i;){o=i>2e3?2e3:i,i-=o;do{a=a+t[n++]|0,r=r+a|0}while(--o);a%=65521,r%=65521}return a|r<<16|0};const i=new Uint32Array((()=>{let e,t=[];for(var i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t})());var n=(e,t,n,a)=>{const r=i,o=a+n;e^=-1;for(let i=a;i>>8^r[255&(e^t[i])];return-1^e};const a=16209;var r=function(e,t){let i,n,r,o,s,l,d,f,c,h,u,w,b,m,k,_,g,p,v,x,y,E,R,A;const Z=e.state;i=e.next_in,R=e.input,n=i+(e.avail_in-5),r=e.next_out,A=e.output,o=r-(t-e.avail_out),s=r+(e.avail_out-257),l=Z.dmax,d=Z.wsize,f=Z.whave,c=Z.wnext,h=Z.window,u=Z.hold,w=Z.bits,b=Z.lencode,m=Z.distcode,k=(1<>>24,u>>>=p,w-=p,p=g>>>16&255,0===p)A[r++]=65535&g;else{if(!(16&p)){if(0==(64&p)){g=b[(65535&g)+(u&(1<>>=p,w-=p),w<15&&(u+=R[i++]<>>24,u>>>=p,w-=p,p=g>>>16&255,!(16&p)){if(0==(64&p)){g=m[(65535&g)+(u&(1<l){e.msg="invalid distance too far back",Z.mode=a;break e}if(u>>>=p,w-=p,p=r-o,x>p){if(p=x-p,p>f&&Z.sane){e.msg="invalid distance too far back",Z.mode=a;break e}if(y=0,E=h,0===c){if(y+=d-p,p2;)A[r++]=E[y++],A[r++]=E[y++],A[r++]=E[y++],v-=3;v&&(A[r++]=E[y++],v>1&&(A[r++]=E[y++]))}else{y=r-x;do{A[r++]=A[y++],A[r++]=A[y++],A[r++]=A[y++],v-=3}while(v>2);v&&(A[r++]=A[y++],v>1&&(A[r++]=A[y++]))}break}}break}}while(i>3,i-=v,w-=v<<3,u&=(1<{const u=h.bits;let w,b,m,k,_,g,p=0,v=0,x=0,y=0,E=0,R=0,A=0,Z=0,S=0,T=0,O=null;const U=new Uint16Array(16),D=new Uint16Array(16);let I,B,N,C=null;for(p=0;p<=o;p++)U[p]=0;for(v=0;v=1&&0===U[y];y--);if(E>y&&(E=y),0===y)return a[r++]=20971520,a[r++]=20971520,h.bits=1,0;for(x=1;x0&&(0===e||1!==y))return-1;for(D[1]=0,p=1;p852||2===e&&S>592)return 1;for(;;){I=p-A,c[v]+1=g?(B=C[c[v]-g],N=O[c[v]-g]):(B=96,N=0),w=1<>A)+b]=I<<24|B<<16|N|0}while(0!==b);for(w=1<>=1;if(0!==w?(T&=w-1,T+=w):T=0,v++,0==--U[p]){if(p===y)break;p=t[i+c[v]]}if(p>E&&(T&k)!==m){for(0===A&&(A=E),_+=x,R=p-A,Z=1<852||2===e&&S>592)return 1;m=T&k,a[m]=E<<24|R<<16|_-r|0}}return 0!==T&&(a[_+T]=p-A<<24|64<<16|0),h.bits=E,0},h={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{Z_FINISH:u,Z_BLOCK:w,Z_TREES:b,Z_OK:m,Z_STREAM_END:k,Z_NEED_DICT:_,Z_STREAM_ERROR:g,Z_DATA_ERROR:p,Z_MEM_ERROR:v,Z_BUF_ERROR:x,Z_DEFLATED:y}=h,E=16180,R=16190,A=16191,Z=16192,S=16194,T=16199,O=16200,U=16206,D=16209,I=e=>(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24);function B(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const N=e=>{if(!e)return 1;const t=e.state;return!t||t.strm!==e||t.mode16211?1:0},C=e=>{if(N(e))return g;const t=e.state;return e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=E,t.last=0,t.havedict=0,t.flags=-1,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Int32Array(852),t.distcode=t.distdyn=new Int32Array(592),t.sane=1,t.back=-1,m},z=e=>{if(N(e))return g;const t=e.state;return t.wsize=0,t.whave=0,t.wnext=0,C(e)},F=(e,t)=>{let i;if(N(e))return g;const n=e.state;return t<0?(i=0,t=-t):(i=5+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?g:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,z(e))},L=(e,t)=>{if(!e)return g;const i=new B;e.state=i,i.strm=e,i.window=null,i.mode=E;const n=F(e,t);return n!==m&&(e.state=null),n};let M,H,j=!0;const K=e=>{if(j){M=new Int32Array(512),H=new Int32Array(32);let t=0;for(;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(c(1,e.lens,0,288,M,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;c(2,e.lens,0,32,H,0,e.work,{bits:5}),j=!1}e.lencode=M,e.lenbits=9,e.distcode=H,e.distbits=5},P=(e,t,i,n)=>{let a;const r=e.state;return null===r.window&&(r.wsize=1<=r.wsize?(r.window.set(t.subarray(i-r.wsize,i),0),r.wnext=0,r.whave=r.wsize):(a=r.wsize-r.wnext,a>n&&(a=n),r.window.set(t.subarray(i-n,i-n+a),r.wnext),(n-=a)?(r.window.set(t.subarray(i-n,i),0),r.wnext=n,r.whave=r.wsize):(r.wnext+=a,r.wnext===r.wsize&&(r.wnext=0),r.whaveL(e,15),inflateInit2:L,inflate:(e,i)=>{let a,o,s,l,d,f,h,B,C,z,F,L,M,H,j,Y,G,X,W,q,J,Q,V=0;const $=new Uint8Array(4);let ee,te;const ie=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(N(e)||!e.output||!e.input&&0!==e.avail_in)return g;a=e.state,a.mode===A&&(a.mode=Z),d=e.next_out,s=e.output,h=e.avail_out,l=e.next_in,o=e.input,f=e.avail_in,B=a.hold,C=a.bits,z=f,F=h,Q=m;e:for(;;)switch(a.mode){case E:if(0===a.wrap){a.mode=Z;break}for(;C<16;){if(0===f)break e;f--,B+=o[l++]<>>8&255,a.check=n(a.check,$,2,0),B=0,C=0,a.mode=16181;break}if(a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&B)<<8)+(B>>8))%31){e.msg="incorrect header check",a.mode=D;break}if((15&B)!==y){e.msg="unknown compression method",a.mode=D;break}if(B>>>=4,C-=4,J=8+(15&B),0===a.wbits&&(a.wbits=J),J>15||J>a.wbits){e.msg="invalid window size",a.mode=D;break}a.dmax=1<>8&1),512&a.flags&&4&a.wrap&&($[0]=255&B,$[1]=B>>>8&255,a.check=n(a.check,$,2,0)),B=0,C=0,a.mode=16182;case 16182:for(;C<32;){if(0===f)break e;f--,B+=o[l++]<>>8&255,$[2]=B>>>16&255,$[3]=B>>>24&255,a.check=n(a.check,$,4,0)),B=0,C=0,a.mode=16183;case 16183:for(;C<16;){if(0===f)break e;f--,B+=o[l++]<>8),512&a.flags&&4&a.wrap&&($[0]=255&B,$[1]=B>>>8&255,a.check=n(a.check,$,2,0)),B=0,C=0,a.mode=16184;case 16184:if(1024&a.flags){for(;C<16;){if(0===f)break e;f--,B+=o[l++]<>>8&255,a.check=n(a.check,$,2,0)),B=0,C=0}else a.head&&(a.head.extra=null);a.mode=16185;case 16185:if(1024&a.flags&&(L=a.length,L>f&&(L=f),L&&(a.head&&(J=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Uint8Array(a.head.extra_len)),a.head.extra.set(o.subarray(l,l+L),J)),512&a.flags&&4&a.wrap&&(a.check=n(a.check,o,L,l)),f-=L,l+=L,a.length-=L),a.length))break e;a.length=0,a.mode=16186;case 16186:if(2048&a.flags){if(0===f)break e;L=0;do{J=o[l+L++],a.head&&J&&a.length<65536&&(a.head.name+=String.fromCharCode(J))}while(J&&L>9&1,a.head.done=!0),e.adler=a.check=0,a.mode=A;break;case 16189:for(;C<32;){if(0===f)break e;f--,B+=o[l++]<>>=7&C,C-=7&C,a.mode=U;break}for(;C<3;){if(0===f)break e;f--,B+=o[l++]<>>=1,C-=1,3&B){case 0:a.mode=16193;break;case 1:if(K(a),a.mode=T,i===b){B>>>=2,C-=2;break e}break;case 2:a.mode=16196;break;case 3:e.msg="invalid block type",a.mode=D}B>>>=2,C-=2;break;case 16193:for(B>>>=7&C,C-=7&C;C<32;){if(0===f)break e;f--,B+=o[l++]<>>16^65535)){e.msg="invalid stored block lengths",a.mode=D;break}if(a.length=65535&B,B=0,C=0,a.mode=S,i===b)break e;case S:a.mode=16195;case 16195:if(L=a.length,L){if(L>f&&(L=f),L>h&&(L=h),0===L)break e;s.set(o.subarray(l,l+L),d),f-=L,l+=L,h-=L,d+=L,a.length-=L;break}a.mode=A;break;case 16196:for(;C<14;){if(0===f)break e;f--,B+=o[l++]<>>=5,C-=5,a.ndist=1+(31&B),B>>>=5,C-=5,a.ncode=4+(15&B),B>>>=4,C-=4,a.nlen>286||a.ndist>30){e.msg="too many length or distance symbols",a.mode=D;break}a.have=0,a.mode=16197;case 16197:for(;a.have>>=3,C-=3}for(;a.have<19;)a.lens[ie[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,ee={bits:a.lenbits},Q=c(0,a.lens,0,19,a.lencode,0,a.work,ee),a.lenbits=ee.bits,Q){e.msg="invalid code lengths set",a.mode=D;break}a.have=0,a.mode=16198;case 16198:for(;a.have>>24,Y=V>>>16&255,G=65535&V,!(j<=C);){if(0===f)break e;f--,B+=o[l++]<>>=j,C-=j,a.lens[a.have++]=G;else{if(16===G){for(te=j+2;C>>=j,C-=j,0===a.have){e.msg="invalid bit length repeat",a.mode=D;break}J=a.lens[a.have-1],L=3+(3&B),B>>>=2,C-=2}else if(17===G){for(te=j+3;C>>=j,C-=j,J=0,L=3+(7&B),B>>>=3,C-=3}else{for(te=j+7;C>>=j,C-=j,J=0,L=11+(127&B),B>>>=7,C-=7}if(a.have+L>a.nlen+a.ndist){e.msg="invalid bit length repeat",a.mode=D;break}for(;L--;)a.lens[a.have++]=J}}if(a.mode===D)break;if(0===a.lens[256]){e.msg="invalid code -- missing end-of-block",a.mode=D;break}if(a.lenbits=9,ee={bits:a.lenbits},Q=c(1,a.lens,0,a.nlen,a.lencode,0,a.work,ee),a.lenbits=ee.bits,Q){e.msg="invalid literal/lengths set",a.mode=D;break}if(a.distbits=6,a.distcode=a.distdyn,ee={bits:a.distbits},Q=c(2,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,ee),a.distbits=ee.bits,Q){e.msg="invalid distances set",a.mode=D;break}if(a.mode=T,i===b)break e;case T:a.mode=O;case O:if(f>=6&&h>=258){e.next_out=d,e.avail_out=h,e.next_in=l,e.avail_in=f,a.hold=B,a.bits=C,r(e,F),d=e.next_out,s=e.output,h=e.avail_out,l=e.next_in,o=e.input,f=e.avail_in,B=a.hold,C=a.bits,a.mode===A&&(a.back=-1);break}for(a.back=0;V=a.lencode[B&(1<>>24,Y=V>>>16&255,G=65535&V,!(j<=C);){if(0===f)break e;f--,B+=o[l++]<>X)],j=V>>>24,Y=V>>>16&255,G=65535&V,!(X+j<=C);){if(0===f)break e;f--,B+=o[l++]<>>=X,C-=X,a.back+=X}if(B>>>=j,C-=j,a.back+=j,a.length=G,0===Y){a.mode=16205;break}if(32&Y){a.back=-1,a.mode=A;break}if(64&Y){e.msg="invalid literal/length code",a.mode=D;break}a.extra=15&Y,a.mode=16201;case 16201:if(a.extra){for(te=a.extra;C>>=a.extra,C-=a.extra,a.back+=a.extra}a.was=a.length,a.mode=16202;case 16202:for(;V=a.distcode[B&(1<>>24,Y=V>>>16&255,G=65535&V,!(j<=C);){if(0===f)break e;f--,B+=o[l++]<>X)],j=V>>>24,Y=V>>>16&255,G=65535&V,!(X+j<=C);){if(0===f)break e;f--,B+=o[l++]<>>=X,C-=X,a.back+=X}if(B>>>=j,C-=j,a.back+=j,64&Y){e.msg="invalid distance code",a.mode=D;break}a.offset=G,a.extra=15&Y,a.mode=16203;case 16203:if(a.extra){for(te=a.extra;C>>=a.extra,C-=a.extra,a.back+=a.extra}if(a.offset>a.dmax){e.msg="invalid distance too far back",a.mode=D;break}a.mode=16204;case 16204:if(0===h)break e;if(L=F-h,a.offset>L){if(L=a.offset-L,L>a.whave&&a.sane){e.msg="invalid distance too far back",a.mode=D;break}L>a.wnext?(L-=a.wnext,M=a.wsize-L):M=a.wnext-L,L>a.length&&(L=a.length),H=a.window}else H=s,M=d-a.offset,L=a.length;L>h&&(L=h),h-=L,a.length-=L;do{s[d++]=H[M++]}while(--L);0===a.length&&(a.mode=O);break;case 16205:if(0===h)break e;s[d++]=a.length,h--,a.mode=O;break;case U:if(a.wrap){for(;C<32;){if(0===f)break e;f--,B|=o[l++]<{if(N(e))return g;let t=e.state;return t.window&&(t.window=null),e.state=null,m},inflateGetHeader:(e,t)=>{if(N(e))return g;const i=e.state;return 0==(2&i.wrap)?g:(i.head=t,t.done=!1,m)},inflateSetDictionary:(e,i)=>{const n=i.length;let a,r,o;return N(e)?g:(a=e.state,0!==a.wrap&&a.mode!==R?g:a.mode===R&&(r=1,r=t(r,i,n,0),r!==a.check)?p:(o=P(e,i,n,n),o?(a.mode=16210,v):(a.havedict=1,m)))},inflateInfo:"pako inflate (from Nodeca project)"};const G=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var X=function(e){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(const t in i)G(i,t)&&(e[t]=i[t])}}return e},W=e=>{let t=0;for(let i=0,n=e.length;i=252?6:e>=248?5:e>=240?4:e>=224?3:e>=192?2:1;J[254]=J[254]=1;var Q=e=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(e);let t,i,n,a,r,o=e.length,s=0;for(a=0;a>>6,t[r++]=128|63&i):i<65536?(t[r++]=224|i>>>12,t[r++]=128|i>>>6&63,t[r++]=128|63&i):(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63,t[r++]=128|i>>>6&63,t[r++]=128|63&i);return t},V=(e,t)=>{const i=t||e.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(e.subarray(0,t));let n,a;const r=new Array(2*i);for(a=0,n=0;n4)r[a++]=65533,n+=o-1;else{for(t&=2===o?31:3===o?15:7;o>1&&n1?r[a++]=65533:t<65536?r[a++]=t:(t-=65536,r[a++]=55296|t>>10&1023,r[a++]=56320|1023&t)}}return((e,t)=>{if(t<65534&&e.subarray&&q)return String.fromCharCode.apply(null,e.length===t?e:e.subarray(0,t));let i="";for(let n=0;n{(t=t||e.length)>e.length&&(t=e.length);let i=t-1;for(;i>=0&&128==(192&e[i]);)i--;return i<0||0===i?t:i+J[e[i]]>t?i:t},ee={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"};var te=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};var ie=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const ne=Object.prototype.toString,{Z_NO_FLUSH:ae,Z_FINISH:re,Z_OK:oe,Z_STREAM_END:se,Z_NEED_DICT:le,Z_STREAM_ERROR:de,Z_DATA_ERROR:fe,Z_MEM_ERROR:ce}=h;function he(e){this.options=X({chunkSize:65536,windowBits:15,to:""},e||{});const t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new te,this.strm.avail_out=0;let i=Y.inflateInit2(this.strm,t.windowBits);if(i!==oe)throw new Error(ee[i]);if(this.header=new ie,Y.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=Q(t.dictionary):"[object ArrayBuffer]"===ne.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=Y.inflateSetDictionary(this.strm,t.dictionary),i!==oe)))throw new Error(ee[i])}function ue(e,t){const i=new he(t);if(i.push(e),i.err)throw i.msg||ee[i.err];return i.result}he.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize,a=this.options.dictionary;let r,o,s;if(this.ended)return!1;for(o=t===~~t?t:!0===t?re:ae,"[object ArrayBuffer]"===ne.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;){for(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),r=Y.inflate(i,o),r===le&&a&&(r=Y.inflateSetDictionary(i,a),r===oe?r=Y.inflate(i,o):r===fe&&(r=le));i.avail_in>0&&r===se&&i.state.wrap>0&&0!==e[i.next_in];)Y.inflateReset(i),r=Y.inflate(i,o);switch(r){case de:case fe:case le:case ce:return this.onEnd(r),this.ended=!0,!1}if(s=i.avail_out,i.next_out&&(0===i.avail_out||r===se))if("string"===this.options.to){let e=$(i.output,i.next_out),t=i.next_out-e,a=V(i.output,e);i.next_out=t,i.avail_out=n-t,t&&i.output.set(i.output.subarray(e,e+t),0),this.onData(a)}else this.onData(i.output.length===i.next_out?i.output:i.output.subarray(0,i.next_out));if(r!==oe||0!==s){if(r===se)return r=Y.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,!0;if(0===i.avail_in)break}}return!0},he.prototype.onData=function(e){this.chunks.push(e)},he.prototype.onEnd=function(e){e===oe&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=W(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var we=he,be=ue,me=function(e,t){return(t=t||{}).raw=!0,ue(e,t)},ke=ue,_e=h,ge={Inflate:we,inflate:be,inflateRaw:me,ungzip:ke,constants:_e};e.Inflate=we,e.constants=_e,e.default=ge,e.inflate=be,e.inflateRaw=me,e.ungzip=ke,Object.defineProperty(e,"__esModule",{value:!0})})); diff --git a/app/src/lib/fastboot/vendor/z-worker-pako.js b/app/src/lib/fastboot/vendor/z-worker-pako.js deleted file mode 100644 index 960967daa763a9bb1ba59c0fb277d2f002e62001..0000000000000000000000000000000000000000 --- a/app/src/lib/fastboot/vendor/z-worker-pako.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";const{Array:e,Object:t,Number:n,Math:s,Error:r,Uint8Array:a,Uint16Array:o,Uint32Array:i,Int32Array:c,Map:l,DataView:u,Promise:h,TextEncoder:f,crypto:p,postMessage:d,TransformStream:g,ReadableStream:w,WritableStream:y,CompressionStream:m,DecompressionStream:_}=self;class b{constructor(e){return class extends g{constructor(t,n){const s=new e(n);super({transform(e,t){t.enqueue(s.append(e))},flush(e){const t=s.flush();t&&e.enqueue(t)}})}}}}const v=[];for(let e=0;256>e;e++){let t=e;for(let e=0;8>e;e++)1&t?t=t>>>1^3988292384:t>>>=1;v[e]=t}class S{constructor(e){this.crc=e||-1}append(e){let t=0|this.crc;for(let n=0,s=0|e.length;s>n;n++)t=t>>>8^v[255&(t^e[n])];this.crc=t}get(){return~this.crc}}class k extends g{constructor(){const e=new S;super({transform(t){e.append(t)},flush(t){const n=new a(4);new u(n.buffer).setUint32(0,e.get()),t.enqueue(n)}})}}const z={concat(e,t){if(0===e.length||0===t.length)return e.concat(t);const n=e[e.length-1],s=z.getPartial(n);return 32===s?e.concat(t):z._shiftRight(t,s,0|n,e.slice(0,e.length-1))},bitLength(e){const t=e.length;if(0===t)return 0;const n=e[t-1];return 32*(t-1)+z.getPartial(n)},clamp(e,t){if(32*e.length0&&t&&(e[n-1]=z.partial(t,e[n-1]&2147483648>>t-1,1)),e},partial:(e,t,n)=>32===e?t:(n?0|t:t<<32-e)+1099511627776*e,getPartial:e=>s.round(e/1099511627776)||32,_shiftRight(e,t,n,s){for(void 0===s&&(s=[]);t>=32;t-=32)s.push(n),n=0;if(0===t)return s.concat(e);for(let r=0;r>>t),n=e[r]<<32-t;const r=e.length?e[e.length-1]:0,a=z.getPartial(r);return s.push(z.partial(t+a&31,t+a>32?n:s.pop(),1)),s}},D={bytes:{fromBits(e){const t=z.bitLength(e)/8,n=new a(t);let s;for(let r=0;t>r;r++)0==(3&r)&&(s=e[r/4]),n[r]=s>>>24,s<<=8;return n},toBits(e){const t=[];let n,s=0;for(n=0;n9007199254740991)throw new r("Cannot hash more than 2^53 - 1 bits");const o=new i(n);let c=0;for(let e=t.blockSize+s-(t.blockSize+s&t.blockSize-1);a>=e;e+=t.blockSize)t._block(o.subarray(16*c,16*(c+1))),c+=1;return n.splice(0,16*c),t}finalize(){const e=this;let t=e._buffer;const n=e._h;t=z.concat(t,[z.partial(1,1)]);for(let e=t.length+2;15&e;e++)t.push(0);for(t.push(s.floor(e._length/4294967296)),t.push(0|e._length);t.length;)e._block(t.splice(0,16));return e.reset(),n}_f(e,t,n,s){return e>19?e>39?e>59?e>79?void 0:t^n^s:t&n|t&s|n&s:t^n^s:t&n|~t&s}_S(e,t){return t<>>32-e}_block(t){const n=this,r=n._h,a=e(80);for(let e=0;16>e;e++)a[e]=t[e];let o=r[0],i=r[1],c=r[2],l=r[3],u=r[4];for(let e=0;79>=e;e++){16>e||(a[e]=n._S(1,a[e-3]^a[e-8]^a[e-14]^a[e-16]));const t=n._S(5,o)+n._f(e,i,c,l)+u+a[e]+n._key[s.floor(e/20)]|0;u=l,l=c,c=n._S(30,i),i=o,o=t}r[0]=r[0]+o|0,r[1]=r[1]+i|0,r[2]=r[2]+c|0,r[3]=r[3]+l|0,r[4]=r[4]+u|0}},I={getRandomValues(e){const t=new i(e.buffer),n=e=>{let t=987654321;const n=4294967295;return()=>(t=36969*(65535&t)+(t>>16)&n,(((t<<16)+(e=18e3*(65535&e)+(e>>16)&n)&n)/4294967296+.5)*(s.random()>.5?1:-1))};for(let r,a=0;anew R.hmacSha1(D.bytes.toBits(e)),pbkdf2(e,t,n,s){if(n=n||1e4,0>s||0>n)throw new r("invalid params to pbkdf2");const a=1+(s>>5)<<2;let o,i,c,l,h;const f=new ArrayBuffer(a),p=new u(f);let d=0;const g=z;for(t=D.bytes.toBits(t),h=1;(a||1)>d;h++){for(o=i=e.encrypt(g.concat(t,[h])),c=1;n>c;c++)for(i=e.encrypt(i),l=0;ld&&cr&&(e=(new n).update(e).finalize());for(let t=0;r>t;t++)s[0][t]=909522486^e[t],s[1][t]=1549556828^e[t];t._baseHash[0].update(s[0]),t._baseHash[1].update(s[1]),t._resultHash=new n(t._baseHash[0])}reset(){const e=this;e._resultHash=new e._hash(e._baseHash[0]),e._updated=!1}update(e){this._updated=!0,this._resultHash.update(e)}digest(){const e=this,t=e._resultHash.finalize(),n=new e._hash(e._baseHash[1]).update(t).finalize();return e.reset(),n}encrypt(e){if(this._updated)throw new r("encrypt on already updated hmac called!");return this.update(e),this.digest(e)}}},A=void 0!==p&&"function"==typeof p.getRandomValues,H="Invalid password",q="Invalid signature",B="zipjs-abort-check-password";function K(e){return A?p.getRandomValues(e):I.getRandomValues(e)}const V=16,x={name:"PBKDF2"},P=t.assign({hash:{name:"HMAC"}},x),T=t.assign({iterations:1e3,hash:{name:"SHA-1"}},x),E=["deriveBits"],M=[8,12,16],N=[16,24,32],U=10,W=[0,0,0,0],L="undefined",O="function",F=typeof p!=L,j=F&&p.subtle,G=F&&typeof j!=L,X=D.bytes,J=class{constructor(e){const t=this;t._tables=[[[],[],[],[],[]],[[],[],[],[],[]]],t._tables[0][0][0]||t._precompute();const n=t._tables[0][4],s=t._tables[1],a=e.length;let o,i,c,l=1;if(4!==a&&6!==a&&8!==a)throw new r("invalid aes key size");for(t._key=[i=e.slice(0),c=[]],o=a;4*a+28>o;o++){let e=i[o-1];(o%a==0||8===a&&o%a==4)&&(e=n[e>>>24]<<24^n[e>>16&255]<<16^n[e>>8&255]<<8^n[255&e],o%a==0&&(e=e<<8^e>>>24^l<<24,l=l<<1^283*(l>>7))),i[o]=i[o-a]^e}for(let e=0;o;e++,o--){const t=i[3&e?o:o-4];c[e]=4>=o||4>e?t:s[0][n[t>>>24]]^s[1][n[t>>16&255]]^s[2][n[t>>8&255]]^s[3][n[255&t]]}}encrypt(e){return this._crypt(e,0)}decrypt(e){return this._crypt(e,1)}_precompute(){const e=this._tables[0],t=this._tables[1],n=e[4],s=t[4],r=[],a=[];let o,i,c,l;for(let e=0;256>e;e++)a[(r[e]=e<<1^283*(e>>7))^e]=e;for(let u=o=0;!n[u];u^=i||1,o=a[o]||1){let a=o^o<<1^o<<2^o<<3^o<<4;a=a>>8^255&a^99,n[u]=a,s[a]=u,l=r[c=r[i=r[u]]];let h=16843009*l^65537*c^257*i^16843008*u,f=257*r[a]^16843008*a;for(let n=0;4>n;n++)e[n][u]=f=f<<24^f>>>8,t[n][a]=h=h<<24^h>>>8}for(let n=0;5>n;n++)e[n]=e[n].slice(0),t[n]=t[n].slice(0)}_crypt(e,t){if(4!==e.length)throw new r("invalid aes block size");const n=this._key[t],s=n.length/4-2,a=[0,0,0,0],o=this._tables[t],i=o[0],c=o[1],l=o[2],u=o[3],h=o[4];let f,p,d,g=e[0]^n[0],w=e[t?3:1]^n[1],y=e[2]^n[2],m=e[t?1:3]^n[3],_=4;for(let e=0;s>e;e++)f=i[g>>>24]^c[w>>16&255]^l[y>>8&255]^u[255&m]^n[_],p=i[w>>>24]^c[y>>16&255]^l[m>>8&255]^u[255&g]^n[_+1],d=i[y>>>24]^c[m>>16&255]^l[g>>8&255]^u[255&w]^n[_+2],m=i[m>>>24]^c[g>>16&255]^l[w>>8&255]^u[255&y]^n[_+3],_+=4,g=f,w=p,y=d;for(let e=0;4>e;e++)a[t?3&-e:e]=h[g>>>24]<<24^h[w>>16&255]<<16^h[y>>8&255]<<8^h[255&m]^n[_++],f=g,g=w,w=y,y=m,m=f;return a}},Q=class{constructor(e,t){this._prf=e,this._initIv=t,this._iv=t}reset(){this._iv=this._initIv}update(e){return this.calculate(this._prf,e,this._iv)}incWord(e){if(255==(e>>24&255)){let t=e>>16&255,n=e>>8&255,s=255&e;255===t?(t=0,255===n?(n=0,255===s?s=0:++s):++n):++t,e=0,e+=t<<16,e+=n<<8,e+=s}else e+=1<<24;return e}incCounter(e){0===(e[0]=this.incWord(e[0]))&&(e[1]=this.incWord(e[1]))}calculate(e,t,n){let s;if(!(s=t.length))return[];const r=z.bitLength(t);for(let r=0;s>r;r+=4){this.incCounter(n);const s=e.encrypt(n);t[r]^=s[0],t[r+1]^=s[1],t[r+2]^=s[2],t[r+3]^=s[3]}return z.clamp(t,r)}},Y=R.hmacSha1;let Z=F&&G&&typeof j.importKey==O,$=F&&G&&typeof j.deriveBits==O;class ee extends g{constructor({password:e,signed:n,encryptionStrength:s,checkPasswordOnly:o}){super({start(){t.assign(this,{ready:new h((e=>this.resolveReady=e)),password:e,signed:n,strength:s-1,pending:new a})},async transform(e,t){const n=this,{password:s,strength:i,resolveReady:c,ready:l}=n;s?(await(async(e,t,n,s)=>{const a=await se(e,t,n,ae(s,0,M[t])),o=ae(s,M[t]);if(a[0]!=o[0]||a[1]!=o[1])throw new r(H)})(n,i,s,ae(e,0,M[i]+2)),e=ae(e,M[i]+2),o?t.error(new r(B)):c()):await l;const u=new a(e.length-U-(e.length-U)%V);t.enqueue(ne(n,e,u,0,U,!0))},async flush(e){const{signed:t,ctr:n,hmac:s,pending:o,ready:i}=this;await i;const c=ae(o,0,o.length-U),l=ae(o,o.length-U);let u=new a;if(c.length){const e=ie(X,c);s.update(e);const t=n.update(e);u=oe(X,t)}if(t){const e=ae(oe(X,s.digest()),0,U);for(let t=0;U>t;t++)if(e[t]!=l[t])throw new r(q)}e.enqueue(u)}})}}class te extends g{constructor({password:e,encryptionStrength:n}){let s;super({start(){t.assign(this,{ready:new h((e=>this.resolveReady=e)),password:e,strength:n-1,pending:new a})},async transform(e,t){const n=this,{password:s,strength:r,resolveReady:o,ready:i}=n;let c=new a;s?(c=await(async(e,t,n)=>{const s=K(new a(M[t]));return re(s,await se(e,t,n,s))})(n,r,s),o()):await i;const l=new a(c.length+e.length-e.length%V);l.set(c,0),t.enqueue(ne(n,e,l,c.length,0))},async flush(e){const{ctr:t,hmac:n,pending:r,ready:o}=this;await o;let i=new a;if(r.length){const e=t.update(ie(X,r));n.update(e),i=oe(X,e)}s.signature=oe(X,n.digest()).slice(0,U),e.enqueue(re(i,s.signature))}}),s=this}}function ne(e,t,n,s,r,o){const{ctr:i,hmac:c,pending:l}=e,u=t.length-r;let h;for(l.length&&(t=re(l,t),n=((e,t)=>{if(t&&t>e.length){const n=e;(e=new a(t)).set(n,0)}return e})(n,u-u%V)),h=0;u-V>=h;h+=V){const e=ie(X,ae(t,h,h+V));o&&c.update(e);const r=i.update(e);o||c.update(r),n.set(oe(X,r),h+s)}return e.pending=ae(t,h),n}async function se(n,s,r,o){n.password=null;const i=(e=>{if(void 0===f){const t=new a((e=unescape(encodeURIComponent(e))).length);for(let n=0;n{if(!Z)return R.importKey(t);try{return await j.importKey("raw",t,n,!1,r)}catch(e){return Z=!1,R.importKey(t)}})(0,i,P,0,E),l=await(async(e,t,n)=>{if(!$)return R.pbkdf2(t,e.salt,T.iterations,n);try{return await j.deriveBits(e,t,n)}catch(s){return $=!1,R.pbkdf2(t,e.salt,T.iterations,n)}})(t.assign({salt:o},T),c,8*(2*N[s]+2)),u=new a(l),h=ie(X,ae(u,0,N[s])),p=ie(X,ae(u,N[s],2*N[s])),d=ae(u,2*N[s]);return t.assign(n,{keys:{key:h,authentication:p,passwordVerification:d},ctr:new Q(new J(h),e.from(W)),hmac:new Y(p)}),d}function re(e,t){let n=e;return e.length+t.length&&(n=new a(e.length+t.length),n.set(e,0),n.set(t,e.length)),n}function ae(e,t,n){return e.subarray(t,n)}function oe(e,t){return e.fromBits(t)}function ie(e,t){return e.toBits(t)}class ce extends g{constructor({password:e,passwordVerification:n,checkPasswordOnly:s}){super({start(){t.assign(this,{password:e,passwordVerification:n}),fe(this,e)},transform(e,t){const n=this;if(n.password){const t=ue(n,e.subarray(0,12));if(n.password=null,t[11]!=n.passwordVerification)throw new r(H);e=e.subarray(12)}s?t.error(new r(B)):t.enqueue(ue(n,e))}})}}class le extends g{constructor({password:e,passwordVerification:n}){super({start(){t.assign(this,{password:e,passwordVerification:n}),fe(this,e)},transform(e,t){const n=this;let s,r;if(n.password){n.password=null;const t=K(new a(12));t[11]=n.passwordVerification,s=new a(e.length+t.length),s.set(he(n,t),0),r=12}else s=new a(e.length),r=0;s.set(he(n,e),r),t.enqueue(s)}})}}function ue(e,t){const n=new a(t.length);for(let s=0;s>>24]),a=~e.crcKey2.get(),e.keys=[n,r,a]}function de(e){const t=2|e.keys[2];return ge(s.imul(t,1^t)>>>8)}function ge(e){return 255&e}function we(e){return 4294967295&e}const ye="deflate-raw";class me extends g{constructor(e,{chunkSize:t,CompressionStream:n,CompressionStreamNative:s}){super({});const{compressed:r,encrypted:a,useCompressionStream:o,zipCrypto:i,signed:c,level:l}=e,h=this;let f,p,d=be(super.readable);a&&!i||!c||([d,f]=d.tee(),f=ke(f,new k)),r&&(d=Se(d,o,{level:l,chunkSize:t},s,n)),a&&(i?d=ke(d,new le(e)):(p=new te(e),d=ke(d,p))),ve(h,d,(async()=>{let e;a&&!i&&(e=p.signature),a&&!i||!c||(e=await f.getReader().read(),e=new u(e.value.buffer).getUint32(0)),h.signature=e}))}}class _e extends g{constructor(e,{chunkSize:t,DecompressionStream:n,DecompressionStreamNative:s}){super({});const{zipCrypto:a,encrypted:o,signed:i,signature:c,compressed:l,useCompressionStream:h}=e;let f,p,d=be(super.readable);o&&(a?d=ke(d,new ce(e)):(p=new ee(e),d=ke(d,p))),l&&(d=Se(d,h,{chunkSize:t},s,n)),o&&!a||!i||([d,f]=d.tee(),f=ke(f,new k)),ve(this,d,(async()=>{if((!o||a)&&i){const e=await f.getReader().read(),t=new u(e.value.buffer);if(c!=t.getUint32(0,!1))throw new r(q)}}))}}function be(e){return ke(e,new g({transform(e,t){e&&e.length&&t.enqueue(e)}}))}function ve(e,n,s){n=ke(n,new g({flush:s})),t.defineProperty(e,"readable",{get:()=>n})}function Se(e,t,n,s,r){try{e=ke(e,new(t&&s?s:r)(ye,n))}catch(s){if(!t)throw s;e=ke(e,new r(ye,n))}return e}function ke(e,t){return e.pipeThrough(t)}const ze="data";class De extends g{constructor(e,n){super({});const s=this,{codecType:r}=e;let a;r.startsWith("deflate")?a=me:r.startsWith("inflate")&&(a=_e);let o=0;const i=new a(e,n),c=super.readable,l=new g({transform(e,t){e&&e.length&&(o+=e.length,t.enqueue(e))},flush(){const{signature:e}=i;t.assign(s,{signature:e,size:o})}});t.defineProperty(s,"readable",{get:()=>c.pipeThrough(i).pipeThrough(l)})}}const Ce=new l,Ie=new l;let Re=0;async function Ae(e){try{const{options:t,scripts:s,config:r}=e;s&&s.length&&importScripts.apply(void 0,s),self.initCodec&&self.initCodec(),r.CompressionStreamNative=self.CompressionStream,r.DecompressionStreamNative=self.DecompressionStream,self.Deflate&&(r.CompressionStream=new b(self.Deflate)),self.Inflate&&(r.DecompressionStream=new b(self.Inflate));const a={highWaterMark:1,size:()=>r.chunkSize},o=e.readable||new w({async pull(e){const t=new h((e=>Ce.set(Re,e)));He({type:"pull",messageId:Re}),Re=(Re+1)%n.MAX_SAFE_INTEGER;const{value:s,done:r}=await t;e.enqueue(s),r&&e.close()}},a),i=e.writable||new y({async write(e){let t;const s=new h((e=>t=e));Ie.set(Re,t),He({type:ze,value:e,messageId:Re}),Re=(Re+1)%n.MAX_SAFE_INTEGER,await s}},a),c=new De(t,r);await o.pipeThrough(c).pipeTo(i,{preventClose:!0,preventAbort:!0});try{await i.close()}catch(e){}const{signature:l,size:u}=c;He({type:"close",result:{signature:l,size:u}})}catch(e){qe(e)}}function He(e){let{value:t}=e;if(t)if(t.length)try{t=new a(t),e.value=t.buffer,d(e,[e.value])}catch(t){d(e)}else d(e);else d(e)}function qe(e){const{message:t,stack:n,code:s,name:r}=e;d({error:{message:t,stack:n,code:s,name:r}})}function Be(e,n,s){return class{constructor(r){const o=this;t.hasOwn(r,"level")&&void 0===r.level&&delete r.level,o.codec=new e(t.assign({},n,r)),s(o.codec,(e=>{if(o.pendingData){const t=o.pendingData;o.pendingData=new a(t.length+e.length);const{pendingData:n}=o;n.set(t,0),n.set(e,t.length)}else o.pendingData=new a(e)}))}append(e){return this.codec.push(e),r(this)}flush(){return this.codec.push(new a,!0),r(this)}};function r(e){if(e.pendingData){const t=e.pendingData;return e.pendingData=null,t}return new a}}addEventListener("message",(({data:e})=>{const{type:t,messageId:n,value:s,done:r}=e;try{if("start"==t&&Ae(e),t==ze){const e=Ce.get(n);Ce.delete(n),e({value:new a(s),done:r})}if("ack"==t){const e=Ie.get(n);Ie.delete(n),e()}}catch(e){qe(e)}})),self.initCodec=()=>{const{Deflate:e,Inflate:t}=((e,t={},n)=>({Deflate:Be(e.Deflate,t.deflate,n),Inflate:Be(e.Inflate,t.inflate,n)}))(pako,{deflate:{raw:!0},inflate:{raw:!0}},((e,t)=>e.onData=t));self.Deflate=e,self.Inflate=t}}(); diff --git a/app/vite.config.js b/app/vite.config.js index 16ef1eca2b4fff59ccabfa1c7372cbb52c18d7fc..3cd15caa950b78f7c4cb6417c8b29be6d17a7eed 100644 --- a/app/vite.config.js +++ b/app/vite.config.js @@ -1,5 +1,20 @@ import { defineConfig } from "vite"; +import { viteStaticCopy } from "vite-plugin-static-copy"; export default defineConfig({ base: "", + plugins: [ + viteStaticCopy({ + targets: [ + { + src: "node_modules/@zip.js/zip.js/dist/z-worker-pako.js", + dest: "vendor", + }, + { + src: "node_modules/pako/dist/pako_inflate.min.js", + dest: "vendor", + }, + ], + }), + ], });